Android 指定宽高的ViewGroup

项目中需要自定义一个密码键盘,不能导入xml文件,只能动态添加控件到ViewGroup中。

指定了ViewGroup的大小,重新计算子控件的宽高。但计算子控件的宽高一直错误,导致子控件的文字一直无法居中,查找了不少资料,终于解决了问题,特此记录。

1、添加控件

void initView() {

for (int i = 0; i < 13; i++) {

TextView button = new TextView(context);

button.setLayoutParams(new LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT));

button.setBackgroundColor(Color.WHITE);

button.setGravity(Gravity.CENTER);

button.setTextColor(Color.BLACK); button.setTextSize(22);

if (i == 3) {

button.setText("Del");

button.setBackgroundColor(Color.YELLOW);

button.setTextColor(Color.WHITE);

} else if (i == 7) {

button.setText("Enter");

button.setBackgroundColor(Color.GREEN);

button.setTextColor(Color.WHITE);

} else if (i == 11) {

button.setText("Cancel");

button.setBackgroundColor(Color.RED);

button.setTextColor(Color.WHITE);

} else {

button.setText("" + i);

}

button.setTag("" + i);

addView(button);

}

TextView textView = new TextView(context);

textView.setLayoutParams(new LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT));

textView.setBackgroundColor(Color.RED);

textView.setGravity(Gravity.CENTER);

textView.setTextColor(Color.BLACK);

textView.setTextSize(22);

addView(textView);

}

2、计算宽高

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

int parentWidth = MeasureSpec.getSize(widthMeasureSpec);

int parentHeight = MeasureSpec.getSize(heightMeasureSpec);

int childWidth = (parentWidth - getPaddingLeft() - getPaddingRight() - 3) / columns;

int childHeight = (parentHeight - getPaddingTop() - getPaddingBottom() - 4) / (rows + 1);

int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY);

int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.EXACTLY);

int childWidthMeasureSpec2 = MeasureSpec.makeMeasureSpec(childWidth * 2 + 1, MeasureSpec.EXACTLY);

int childHeightMeasureSpec2 = MeasureSpec.makeMeasureSpec(childHeight * 2 + 1, MeasureSpec.EXACTLY);

int childWidthMeasureSpec3 = MeasureSpec.makeMeasureSpec(parentWidth, MeasureSpec.EXACTLY);

int childCount = getChildCount();

for (int i = 0; i < childCount; i++) {

View child = getChildAt(i);

LayoutParams lp = child.getLayoutParams();

if (i == 3 || i == 7) {

measureChild(child, childWidthMeasureSpec, childHeightMeasureSpec2);

child.measure(childWidthMeasureSpec, childHeightMeasureSpec2);

} else if (i == 12) {

measureChild(child, childWidthMeasureSpec2, childHeightMeasureSpec);

child.measure(childWidthMeasureSpec2, childHeightMeasureSpec);

} else if (i == 13) {

 measureChild(child, childWidthMeasureSpec3, childHeightMeasureSpec);

child.measure(childWidthMeasureSpec3, childHeightMeasureSpec);

} else {

measureChild(child, childWidthMeasureSpec, childHeightMeasureSpec);

child.measure(childWidthMeasureSpec, childHeightMeasureSpec);

}

}

setMeasuredDimension(parentWidth, parentHeight);

}

给子控件计算出宽高,重写onLayout方法开始布局

protected void onLayout(boolean changed, int l, int t, int r, int b)

{

int height = b - t;

int width = r - l;

int gridW = width / columns;

int gridH = height / (rows + 1);

int inputH = gridH;

int left = 0;

int top = 1;

View child;

int index;

top += inputH;

for (int i = 0; i < rows; i++) {

for (int j = 0; j < columns; j++) {

index = i * columns + j;

child = this.getChildAt(index);

if (child == null) return;

//Log.i(TAG, "index = " + index + " child.getWidth() = " + child.getMeasuredWidth() + " child.getHeight() = " + child.getMeasuredHeight());

if (index == 13) {

child.layout(3, 0, child.getMeasuredWidth(), child.getMeasuredHeight());

break;

}

int ordel = i * columns + j;

switch (ordel) {

case 3:// delete

child.layout(3 + 3 * gridW, top, 3 * gridW + gridW, 2 * gridH + 2 + inputH);

break;

case 7:// enter

child.layout(3 + 3 * gridW, 3 + 2 * gridH + inputH, 3 * gridW + gridW, 4 * gridH + inputH);

break;

case 11:// cancel

child.layout(0, 3 + 3 * gridH + 1 + inputH, gridW, 4 * gridH + inputH);

break;

case 12:// 0

child.layout(gridW + 1, 3 + 3 * gridH + 1 + inputH, 2 + gridW + 2 * gridW, 4 * gridH + inputH);

break;

default: left = j * gridW + j;

child.layout(left, top, left + gridW, top + gridH);

break;

}

}

top += gridH + 1;

}

}

参考文章:https://www.jianshu.com/p/12d37bf44e60

你可能感兴趣的:(Android,自定义viewgroup,android)