如题,我自定义了一个ViewGroup,onMeasure和onLayout都做了常规处理,然后我在xml里或是动态使用,在里面放置View可以正常显示完全没有问题,可是里面放一个ViewGroup(如LinearLayout)就不行了。子ViewGroup的大小和位置没有问题,问题是子ViewGroup里面的子View的大小和位置出现了问题(没有按照我写的布局的方式排列,大小也不受我写的布局控制)!如下,第一个ImageButton正常,第二个放在LinearLayout的ImageButton就不正常了,对它设置的属性完全无效<com.example.swipeview.MyViewGroup
        android:id="@+id/swap_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        
        <ImageButton 
            android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/background_dark"
        android:src="@drawable/ic_action_search"
            />
        
        <LinearLayout 
            android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
            
            <ImageButton 
            android:id="@+id/btn"
            android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/darker_gray"
        android:src="@drawable/ic_launcher"
            />
            
        </LinearLayout>
        
        
    </com.example.swipeview.MyViewGroup>
    百度google了一下发现有类似问题的帖子很多,但是都没有解答如果我的问题描述不够清楚,大家可以看看这个帖子
http://topic.csdn.net/u/20110524/11/dcde4122-fdb6-4852-92dd-7f35e4dc0c7f.html#top“心中疑惑:我认为我只要在这里调用child的layout(int,int,int,int)方法给出它的位置和宽高就可以了
如果child本身是一个ViewGroup的话它是否应该自己去管理它本身内部的child的位置和宽度呢???

解决方案 »

  1.   

    解决方法1,把child.measure移动到onMeasure中就可以了
    解决方法2,不继承viewgroup,而是继承framelayout,因为framelayout会替你做child.measure要记得把onlayout中的child.measure去掉。我猜测在onmeasure和onlayout之间还有很多别的东西要执行,如果把child.measure放到onlayout中来做,就会导致在onlayout开始时有些数据没有准备好,而这些数据本该在onlayout开始之前就准备好了。
      

  2.   


    我就是继承FrameLayout的,我也是在onMeasure中对child执行measure的,onLayout中我并没有对child进行measure,onLayout中我只执行child.layout
    但是这样,问题依旧
      

  3.   

    如果是继承FrameLayout,就不要重写onMeasure了,下面这段代码就可以正确显示
    public class MyViewGroup extends FrameLayout {    public MyViewGroup(Context context, AttributeSet attrs) {
            super(context, attrs);
            
        }    public MyViewGroup(Context context) {
            super(context);
            
        }
        
        @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
    // TODO Auto-generated method stub
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override
        protected void onLayout(boolean arg0, int l, int t, int r, int b) {
            
            int count = this.getChildCount();
            
            for(int i = 0;i < count;i++){
                View child = this.getChildAt(i);
                child.setVisibility(View.VISIBLE);
                //child.measure(r-l, b-t);
                int x = l;
                int y = t;
    //心中疑惑:我认为我只要在这里调用child的layout(int,int,int,int)方法给出它的位置和宽高就可以了
    //如果child本身是一个ViewGroup的话它是否应该自己去管理它本身内部的child的位置和宽度呢???
                child.layout(x,y,x + getWidth(),y + getHeight());
            }
        }
        
    }
      

  4.   


    对,你是对的。继承FrameLayout不重写onMeasure就正常了不过为什么重写onMeasure就不行了。。和为什么继承ViewGroup重写onMeasure也不行呢
      

  5.   

    继承viewgroup要重写onMeasure,下面的代码是可以的,public class MyViewGroup extends ViewGroup {    public MyViewGroup(Context context, AttributeSet attrs) {
            super(context, attrs);
            
        }    public MyViewGroup(Context context) {
            super(context);
            
        }
        
        @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
    // TODO Auto-generated method stub
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int count = this.getChildCount();
            
            for(int i = 0;i < count;i++){
                View child = this.getChildAt(i);
                
                child.measure(widthMeasureSpec, heightMeasureSpec);        }
    } @Override
        protected void onLayout(boolean arg0, int l, int t, int r, int b) {
            
            int count = this.getChildCount();
            
            for(int i = 0;i < count;i++){
                View child = this.getChildAt(i);
                child.setVisibility(View.VISIBLE);
                //child.measure(r-l, b-t);
                int x = l;
                int y = t;
    //心中疑惑:我认为我只要在这里调用child的layout(int,int,int,int)方法给出它的位置和宽高就可以了
    //如果child本身是一个ViewGroup的话它是否应该自己去管理它本身内部的child的位置和宽度呢???
                child.layout(x,y,x + getWidth(),y + getHeight());
            }
        }
        
    }