浅写重写ViewGroup和View(未完)


在自定义控件中,可以重新定义android没有个控件。继承VIew或者ViewGroup。


一. 重写View:

1.测量
 onMeasure(int widthMeasureSpec, int heightMeasureSpec) ;在这个函数中测量控件的大小。
MeasureSpec类是个32位int。高2位了Mode,低30位是具体宽高的大小。
Mode 分三类:
EXACTLY:一般当layout_width或则layout_height为match_parent或则指定数值时,Mode为EXACTLY。
AT_MOST:一般当layout_width或则layout_height为wrap_content时。
UNSPECIFIED。
VIew中默认onMeasurea(),只支持EXACTLY。要想自定义控件支持wrap_content,必须在onMeasure中计算宽高。在onDraw()中绘画。
测量完成后,设置空间的宽高。
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    mheight = measuredHeight(heightMeasureSpec);
    mwidth = measuredWidth(widthMeasureSpec);
    setMeasuredDimension(mwidth, mheight);
}

 private  int measuredWidth(int width){
     int result = 0;
     int specMode = MeasureSpec.getMode(width);
     int specSize = MeasureSpec.getSize(width);
     if(specMode == MeasureSpec.EXACTLY){
         result = specSize;
         Log.i("width", "specMode = MeasureSpec.EXACTLY"+ ",   specSize= "+ specSize+ ",  result = "+result);
     }else{
         result = 200;
         if(specMode == MeasureSpec.AT_MOST){
             result = result< specSize?result:specSize;
             Log.i("width", "specMode = MeasureSpec.AT_MOST"+",   specSize= "+ specSize+ ",  result = "+result);
         }

         if(specMode == MeasureSpec.UNSPECIFIED){
             Log.i("width", "specMode = MeasureSpec.AT_MOST");
         }
     }

     return result;

 }
measuredHeight()和measuredWidth()类似。

2. 

一. 重写ViewGroup:
ViewGroup是容器。其中包括多个view。
onMeasure(int widthMeasureSpec, int heightMeasureSpec)中,测量子view和自己大小
onLayout()是抽象方法,自定义的ViewGroup必须实现该方法,在该方法中对子控件进行布局。
在onLayout()中调用子View的layout()方法。

1. 如下:我这只是简单的根据ViewGrouP大小划分子控件大小。
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    if (changed) {
        int count = getChildCount();
        int height = (b-t) / (count + 1);
        Log.i("parent" , "l = " + l + ",t = " + t + ",r = " + r + ",b = " + b);
        Log.i("child  height", String.valueOf(height));
        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);
            Log.i("child" + i, "l = " + l + ",t = " + i * height + ",r = " + r + ",b = " + (i + 1) * height);
            child.layout(l, i * height, r, (i + 1) * height);//确定子控件的位置和大小。
        }
    }
}

2. 也可以根据子控件的测量后的大小进行布局。这里只是线性竖直排列。
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    if (changed) {
        int count = getChildCount();
        int height = 0;
        Log.i("viewgroup", ":  l = " + l + ",t = " + t + ",r = " + r + ",b = " + b);
        // Log.i("child  height", String.valueOf(height));
        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);
            int cheight = child.getMeasuredHeight();  //获得子控件的高度
            int cwidth = child.getMeasuredWidth();   //获得子控件的宽度

            Log.i("viewgroup", "child: " + i + ",  l = " + l + ",t = " + (10 + height) + ",r = " + (l + cwidth) + ",b = " + (10 + height + cheight));
            child.layout(l, 10 + height, l + cwidth, 10 + height + cheight);
            height += cheight;
        }
    }

}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值