项目中需要自定义一个密码键盘,不能导入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