您的位置:首页 > 移动开发 > Android开发

覆写onLayout进行layout,含自定义ViewGroup例子

2013-03-19 18:05 381 查看
一、自定义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);  
    }  
      
      
      
}  

二、 疑问

代码添加view和布局中添加view的区别?
1. 代码中添加 ViewGroup

[plain]
view plaincopyprint?

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);  

[align=left]onLayout输出信息:[/align]

[plain]
view plaincopyprint?

changed = true, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 130, measureHieght = 130  
changed = true, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 80, measureHieght = 80  
changed = false, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 130, measureHieght = 130  
changed = false, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 80, measureHieght = 80  

[align=left]
[/align]

2. xml中配置添加ViewGroup

[plain]
view plaincopyprint?

<? xml version = "1.0" encoding = "utf-8" ?>  
< com.androiddemo.CustomViewGroup xmlns:android =  
"http://schemas.android.com/apk/res/android"  
    android:id = "@+id/custom_viewgroup"  
    android:layout_width = "fill_parent"  
    android:layout_height = "wrap_content" >  
  
    < TextView  
        android:layout_width = "130dip"  
        android:layout_height = "130dip"  
        android:background = "@color/blue"  
        android:text = "@string/first_childview_name" />  
  
    < TextView  
        android:layout_width = "80dip"  
        android:layout_height = "80dip"  
        android:background = "@color/red"  
        android:text = "@string/second_childview_name" />  
  
</ com.androiddemo.CustomViewGroup >  

[align=left]
[/align]
[align=left]onLayout输出信息:? Width和 Height并不是TextView中设置的固定值[/align]

[plain]
view plaincopyprint?

changed = true, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 195, measureHieght = 195  
changed = true, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 120, measureHieght = 120  
changed = false, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 195, measureHieght = 195  
changed = false, left = 0, top = 0, right = 480, bottom = 724, measureWidth = 120, measureHieght = 120  

三 、扩展

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

[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流程上
http://blog.csdn.net/aaa2832/article/details/7844904
细说view流程下
http://blog.csdn.net/aaa2832/article/details/7849400

昨天晚上因为CSDN博客维护,没能发出来
今日计划: 自定义CustomViewGroup  + 自定义Adapter

原文地址:http://blog.csdn.net/love_world_/article/details/8108970
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android