标签:界面 viewgroup onmeasure onlayout
1. EXACTLY
表示父视图希望子视图的大小应该是由specSize的值来决定的,系统默认会按照这个规则来设置子视图的大小,开发人员当然也可以按照自己的意愿设置成任意的大小。
2. AT_MOST
表示子视图最多只能是specSize中指定的大小,开发人员应该尽可能小得去设置这个视图,并且保证不会超过specSize。系统默认会按照这个规则来设置子视图的大小,开发人员当然也可以按照自己的意愿设置成任意的大小。
3. UNSPECIFIED
表示开发人员可以将视图按照自己的意愿设置成任意的大小,没有任何限制。这种情况比较少见,不太会用到。
关于测量的问题可以看看LinearLayout、RelativeLayout这些是怎么实现的,加深理解。
@Override
protected abstract void onLayout(boolean changed,
int l, int t, int r, int b);
可以看它是一个抽象的方法,所以我们所有的实现类都需要来实现这个方法,自己来告诉系统我们需要怎么去排版我们的界面,像LinearLayout、RelativeLayout等布局,都是重写了这个方法,然后在内部按照各自的规则对子视图进行布局的。由于LinearLayout和RelativeLayout的布局规则都比较复杂,就不单独拿出来进行分析了。public class SimpleVertical extends ViewGroup {
public SimpleVertical(Context context) {
super(context);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int totalheight = 0;
int childcount = getChildCount();
for (int i = 0; i < childcount; i++) {
View childView = getChildAt(i);
if (childView.getVisibility() != GONE) {
childView.layout(0, totalheight, childView.getMeasuredWidth(), totalheight+childView.getMeasuredHeight()); //设置自己放置的位置
totalheight+=childView.getMeasuredHeight();//计算高度的开始
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
if (childView.getVisibility() != GONE) {
LayoutParams childLp = childView.getLayoutParams(); // 获取layout参数
int childWidthMeasureSpec = getChildMeasureSpec(
widthMeasureSpec, getPaddingLeft() + getPaddingRight(),
childLp.width); // 调用VIewGroup的封装的方法
int childHeightMeasureSpec = getChildMeasureSpec(
widthMeasureSpec, getPaddingTop() + getPaddingBottom(),
childLp.height);
childView
.measure(childWidthMeasureSpec, childHeightMeasureSpec); // 最重要的就是告诉自己测量
}
}
// measureChildren(widthMeasureSpec, heightMeasureSpec);
// 也可以调用ViewGroup这个方法
super.onMeasure(widthMeasureSpec, heightMeasureSpec); // 记住调用这个方法不然会报错,其实它也是调用的setMeasuredDimension这个方法
}
}所有的注释我都写在上面了然后我们来写一个测试的Activity,我直接贴出oncreate里面的代码了。也很简单<span style="font-size:14px;">SimpleVertical simpleVertical = new SimpleVertical(this);
for (int i = 0; i < 12; i++) {
TextView textView = getTextView("android自定义控件系列教程----视图的测量和布局");
textView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "</span><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:12px;">android自定义控件系列教程----视图的测量和布局</span></span><span style="font-size:14px;">", 0).show();
}
});
simpleVertical.addView(textView);
}
setContentView(simpleVertical);</span>可以看到我们不但把我们自己写得控件写上了,还给它添加了一个点击事件,点击上去也是没有问题的,这样我们就简单的实现了Linearlayotu的垂直布局了,想要跟深入的理解这里的写法,我的建议是去看Linearlayotu,RelaytiveLayout这一类容器控件的写法。标签:界面 viewgroup onmeasure onlayout
原文地址:http://blog.csdn.net/codebob/article/details/42238331