标签:界面 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