关于自定义Layout或者ViewGroup总结

关于自定义Layout或者ViewGroup总结

先看一下代码,然后我会根据代码具体分析:

package com.yld.startvideodemo;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

/**
 * @author yld
 * @create 2019-02-28 9:33
 */
public class CustomLayout extends ViewGroup {

    public CustomLayout(Context context) {
        super(context);
    }

    public CustomLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    /**
     *widthMeasureSpec 包含了了父view的width属性的模式和尺寸
     *heightMeasureSpec 包含了了父view的height属性的模式和尺寸
     */

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
       int childWidthSpec = 0;
       int childHeightSpec = 0;
       //表示子view在父view中的可使用宽度
       int usedWidth = 0;
       //表示子view在父view中的可使用高度
       int usedHeight = 0;
       for (int i = 0 ; i < getChildCount() ; i ++){
          View childView =  getChildAt(i);
          LayoutParams layoutParams = childView.getLayoutParams();
          //widthMeasureSpec 是一个int类型的数据,取32位二进制数中前两位作为mode值
          //后30位为size值
          int widthMode = MeasureSpec.getMode(widthMeasureSpec);
          int withSize = MeasureSpec.getSize(widthMeasureSpec);
            //heightMeasureSpec 是一个int类型的数据,取32位二进制数中前两位作为mode值
          //后30位为size值
          int heightMode = MeasureSpec.getMode(heightMeasureSpec);
          int heightSize = MeasureSpec.getSize(heightMeasureSpec);
          switch (layoutParams.width){
              case LayoutParams.MATCH_PARENT:
                  if(widthMode == MeasureSpec.EXACTLY&&widthMode==MeasureSpec.AT_MOST){
                      childWidthSpec = MeasureSpec.makeMeasureSpec(widthSize - usedWidth,MeasureSpec.EXACTLY );
                  }else{
                      childWidthSpec = MeasureSpec.makeMeasureSpec(0,MeasureSpec.UNSPECIFIED );
                  }
                  break;
              case LayoutParams.WRAP_CONTENT:
                  if(widthMode == MeasureSpec.EXACTLY&&widthMode==MeasureSpec.AT_MOST){
                      childWidthSpec = MeasureSpec.makeMeasureSpec(widthSize - usedWidth,MeasureSpec.AT_MOST );
                  }else{
                      childWidthSpec = MeasureSpec.makeMeasureSpec(0,MeasureSpec.UNSPECIFIED );
                  }
                  break;
              default:
                  childWidthSpec = MeasureSpec.makeMeasureSpec(layoutParams.width,MeasureSpec.EXACTLY );

                  break;
          }
           switch (layoutParams.height){
               case LayoutParams.MATCH_PARENT:
                   if(heightMode == MeasureSpec.EXACTLY&&heightMode==MeasureSpec.AT_MOST){
                       childHeightSpec = MeasureSpec.makeMeasureSpec(heightSize - usedHeight,MeasureSpec.EXACTLY );
                   }else{
                       childHeightSpec = MeasureSpec.makeMeasureSpec(0,MeasureSpec.UNSPECIFIED );
                   }
                   break;
               case LayoutParams.WRAP_CONTENT:
                   if(heightMode == MeasureSpec.EXACTLY&&heightMode==MeasureSpec.AT_MOST){
                       childHeightSpec = MeasureSpec.makeMeasureSpec(heightSize - usedHeight,MeasureSpec.AT_MOST );
                   }else{
                       childHeightSpec = MeasureSpec.makeMeasureSpec(0,MeasureSpec.UNSPECIFIED );
                   }
                   break;
               default:
                   childHeightSpec = MeasureSpec.makeMeasureSpec(layoutParams.width,MeasureSpec.EXACTLY );

                   break;
           }
           //下面的代码需要验证以后方可使用
           usedWidth = MeasureSpec.getSize(childWidthSpec);
           usedHeight = MeasureSpec.getSize(childHeightSpec);
           setMeasuredDimension(childWidthSpec,childHeightSpec);

       }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int top = 0;
        for (int i = 0 ; i < getChildCount() ; i ++) {
            View childView = getChildAt(i);
            int width = childView.getMeasuredWidth();
            int height = childView.getMeasuredHeight();
            childView.layout(0,top,width,top+height);
            top += height;
        }
    }
}

从代码中可以看到主要是重写了onMeasure()and onLayout()两个方法

1.其中在onMeasure()方法中通过遍历父view中所包含的子view,然后对其进行测量

2.对子view进行测量时通过以下方法:

MeasureSpec.makeMeasureSpec(int measureSize,int measureMode );

在方法中传入计算结果并为其指定测量模式。

3.最后将测量结果进行暂时保存。

4.在onLayout()方法中通过遍历父view中所包含的子view,通过以下代码:

   childView.layout(int left,int top,int right,int bottom);

根据自己的需求指定子view的显示位置.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值