您的位置:首页 > 其它

自定义view(四)覆写onLayout进行layout,含自定义ViewGroup

2014-04-22 21:25 330 查看
本文转自http://blog.csdn.net/androiddevelop/article/details/8108970
视图的绘制仅在Framework层分为三个阶段measure,layout,draw。前一篇博文《 覆写onMeaure进行measure操作》
关于如何覆写onMeasure, 其目的是为了测量视图的大小也就是第一阶段,如果不了解或者关于onMeasure有什么疑惑可以了解下。 本篇博文是关于如何覆写onLayout,其目的是为了指定视图的显示位置,方法执行的前后顺序是在onMeasure之后,因为视图肯定是只有知道大小的情况下,才能确定怎么摆放。

一、自定义ViewGroup例子

例子代码 - 纵向显示两个TextView

(1)编写CustomViewGroup

[plain] view
plaincopyprint?

1. CustomViewGroup继承自ViewGroup,ViewGroup是所有Layout的父类

public class CustomViewGroup extends ViewGroup {

}

2. 覆写View.onMeasure回调函数,用于计算所有child view的宽高,这里偷懒没有进行MeasureSpec模式判断

[plain] view
plaincopyprint?

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

int widthSize = MeasureSpec.getSize(widthMeasureSpec);

int heightSize = MeasureSpec.getSize(heightMeasureSpec);

measureChildren(widthMeasureSpec, heightMeasureSpec);

setMeasuredDimension(widthSize, heightSize);

}

3. 覆写ViewGroup.onLayout回调函数,用于指定所有child View的位置

[plain] view
plaincopyprint?

@Override

protected void onLayout(boolean changed, int left, int top, int right, int bottom) {

int mTotalHeight = 0;

// 遍历所有子视图

int childCount = getChildCount();

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

View childView = getChildAt(i);

// 获取在onMeasure中计算的视图尺寸

int measureHeight = childView.getMeasuredHeight();

int measuredWidth = childView.getMeasuredWidth();

childView.layout(left, mTotalHeight, measuredWidth, mTotalHeight + measureHeight);

mTotalHeight += measureHeight;

Log.e(TAG, "changed = " + changed

+ ", left = " + left + ", top = " + top

+ ", right = " + right + ", bottom = " + bottom

+ ", measureWidth = " + measuredWidth + ", measureHieght = " + measureHeight);

}

}

3.1 onLayout回调函数参数:
left, top, right, bottom是当前ViewGroup整个在屏幕上的位置,手机屏幕是480 * 800 ,其中高度去除状态栏和title大概724
如果页面只有此ViewGroup则个参数的值

left = 0, top = 0, right = 480, bottom = 724



在此ViewGroup的上面放置一个TextView当期回调的参数值
left = 0, top = 25, right = 480, bottom = 724



3.2 child.layout如何填写参数
View是一个矩形,right和bottom也可以通过以下计算获得,其中Width 和 Height由onMeasure最终设置和决定

right = left + width

bottom = top + height

(2)创建Activity

[plain] view
plaincopyprint?

public class CustomViewGroupActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

CustomViewGroup customViewGroup = new CustomViewGroup(this);

customViewGroup.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));

// 添加子视图

TextView textViewOne = new TextView(this);

textViewOne.setText("a child view");

textViewOne.setBackgroundColor(Color.BLUE);

textViewOne.setLayoutParams(new LayoutParams(130, 130));

customViewGroup.addView(textViewOne);

TextView textViewTwo = new TextView(this);

textViewTwo.setText("b child view");

textViewTwo.setBackgroundColor(Color.RED);

textViewTwo.setLayoutParams(new LayoutParams(80, 80));

customViewGroup.addView(textViewTwo);

setContentView(customViewGroup);

}

}

二 、扩展

× 三个方法的区别?后这个方法最终还是调用第一个方法

[plain] view
plaincopyprint?

childView.measure(widthMeasureSpec, heightMeasureSpec);

measureChild(childView, widthMeasureSpec, heightMeasureSpec);

measureChildren(widthMeasureSpec, heightMeasureSpec);

× 哪些视图属性影响 measure? padding、margin

× 哪些视图属性 影响 layout? gravity

× view的上下左右和measurespec width和height的关系 ?

三、资料
Android官方文档:
Layouts
http://developer.android.com/guide/topics/ui/declaring-layout.html

细说view流程上
/article/1382125.html
细说view流程下
/article/1382124.html

2013-03-31 更新与onMeasure关联博文
2013-06-20 xiaoxia19920920 兄帮助解决一个疑惑,代码与xml设置大小的不同。一个单位是px一个是dip。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: