美文网首页Android自定义View
自定义ViewGroup(一)

自定义ViewGroup(一)

作者: NoBugException | 来源:发表于2018-08-06 17:38 被阅读14次

    场景:

    自定义一个ViewGroup, 使得所有的子view垂直摆放。

    学习自定义ViewGroup(一)的前提条件:
    Android屏幕适配及DisplayMetrics解析
    Android onMeasure、Measure、measureChild、measureChildren 的一些区别

    下面开始学习自定义ViewGroup的第一课:

    先展示代码:

    import android.content.Context;
    import android.os.Build;
    import android.support.annotation.RequiresApi;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.View;
    import android.view.ViewGroup;
    
    public class ViewGroupDemo1 extends ViewGroup{
    
        public ViewGroupDemo1(Context context) {
        super(context);
        }
    
        public ViewGroupDemo1(Context context, AttributeSet attrs) {
        super(context, attrs);
        }
    
        public ViewGroupDemo1(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        }
    
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        public ViewGroupDemo1(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//重写父类的onMeasure方法
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);//测量父布局
        Log.d("ViewGroupDemo1", "==========测量===========");
        measureChildren(widthMeasureSpec, heightMeasureSpec);//测量所有的子布局
        }
    
        @Override
        protected void onLayout(boolean changed, int left, int top, int right, int bootom) {//重写父类的onLayout方法
        Log.d("ViewGroupDemo1", "==========onLayout===========");
    
        int height = 0;
        View child;
         //遍历所有的子布局
        for(int i=0;i<getChildCount();i++){
            //获取子布局
            child = getChildAt(i);
            //摆放
            child.layout(0, height, child.getMeasuredWidth(), height + child.getMeasuredHeight());
            //计算下一个子布局摆放的高度
            height = height + child.getMeasuredHeight();
        }
        }
    }
    
    
    <com.hezuo.viewgroup1.viewgroupdemo.ViewGroupDemo1
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <Button
            android:layout_width="200dp"
            android:layout_height="50dp"
            android:text="战三"/>
        <Button
            android:layout_width="200dp"
            android:layout_height="50dp"
            android:text="战三阿萨德"/>
        <Button
            android:layout_width="200dp"
            android:layout_height="50dp"
            android:text="战三儿童"/>
        <Button
            android:layout_width="200dp"
            android:layout_height="50dp"
            android:text="日太阳能"/>
        <Button
            android:layout_width="200dp"
            android:layout_height="50dp"
            android:text="似人非人温柔温柔"/>
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="奥术大师大多"/>
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="让他一人一人头"/>
    </com.hezuo.viewgroup1.viewgroupdemo.ViewGroupDemo1>
    

    展示效果:


    图片.png

    自定义ViewGroup必须重写的两个方法分别是:onMeasure、onLayout

    (1)onMeasure -- 测量
    1. 必须测量viewGroup本身
      super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    2. 必须测量所有的子布局
      measureChildren(widthMeasureSpec, heightMeasureSpec);
    (2)onLayout -- 布局的摆放
    view.layout(左, 上, 右, 下);
    
    遗留问题:

    根据日志打印发现几个特别的现象
    (1)当viewGroup布局有match_parent或者fill_parent时,执行的顺序是

    onMeasure -- onMeasure -- onLayout
    

    (2)当viewGroup布局是wrap_content或者固定数值的时候,执行顺序是

    onMeasure  -- onLayout
    

    (3)onMeasure 和onLayout总是执行了两个轮回,即:

    onMeasure -- onMeasure -- onLayout -- onMeasure -- onMeasure -- onLayout
    
    或者
    
    onMeasure  -- onLayout -- onMeasure  -- onLayout
    

    一个轮回为什么会执行两次onMeasure ?(1)和(2)两种情况有什么区别 ?为什么会执行两个轮回 ?

    导航:

    Android屏幕适配及DisplayMetrics解析
    Android onMeasure、Measure、measureChild、measureChildren 的一些区别
    自定义ViewGroup(一)
    自定义ViewGroup(二)
    自定义ViewGroup(三)
    自定义ViewGroup(四)
    自定义ViewGroup(五)

    相关文章

      网友评论

        本文标题:自定义ViewGroup(一)

        本文链接:https://www.haomeiwen.com/subject/cotgvftx.html