Android 自定义View总结 —— onLayout()

来源:互联网 发布:淘宝买手机退货的条件 编辑:程序博客网 时间:2024/05/17 22:32

说明:本博客为原创,转载请注明出处 CSDN-ANDROID笔记栈
由于作者水平有限,错误在所难免,请见谅,可以留言,本人会及时改正


索引

  • onLayout
  • Demo


onLayout

自定义View继承ViewGroup必须要实现这个方法,该方法实现了所有子View的具体位置

protected void onLayout(boolean changed, int left, int top, int right, int bottom){// changed,如果View大小改变 或者位置改变为true// left,top,right,bottom 是左上右下值,这个值是相对于它的ParentView而言的。//View的大小是基于一个矩形来确定的,四个点可以确定一个矩形的位置及大小。// 10,10,30,40的意思是当前View距离ParentView的左边距为10,上边距为10,当前View的宽度为20,高度为30}
//真正的layout入口是layout方法public void layout(int l, int t, int r, int b){...    onLayout();...}

Demo

GitHub地址: GitHub
环境: Windows7+JAVA8
IDE: AndroidStdio2.2.2
compileSdkVersion:24
测试设备:Nexus5(6.0.1)

运行结果截图
ViewGroup onLayout

自定义ViewGroup实现了如图所示的布局

//xml源码...//DLCustomViewGroup 宽高都是match_parent的,但是在onMeasure方法中改变了这个值 <com.neulion.android.dl.customviewdemo.widget.DLCustomViewGroup            android:layout_width="match_parent"            android:layout_height="match_parent"            android:background="#ffeb3b">        <com.neulion.android.dl.customviewdemo.widget.DLCustomView                android:layout_width="48dp"                android:layout_height="48dp"                android:background="#ff0000" />        <com.neulion.android.dl.customviewdemo.widget.DLCustomView                android:layout_width="48dp"                android:layout_height="48dp"                android:background="#00ff00" />        <com.neulion.android.dl.customviewdemo.widget.DLCustomView                android:layout_width="48dp"                android:layout_height="48dp"                android:background="#0000ff" />        <com.neulion.android.dl.customviewdemo.widget.DLCustomView                android:layout_width="48dp"                android:layout_height="48dp"                android:background="#000000" />    </com.neulion.android.dl.customviewdemo.widget.DLCustomViewGroup>...
// DLCustomViewGroup部分源码protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){    //ViewGroup自己测量所有子View的大小,该方法是ViewGroup自带的    measureChildren(widthMeasureSpec, heightMeasureSpec);    //计算所有子View的高度(类似于LinearLayout垂直布局)    int childrenHeight = 0;    //遍历所有子View    for (int i = 0; i < getChildCount(); i++){        childrenHeight += getChildAt(i).getMeasuredHeight();    }    //height并没有解析xml属性,这里只是做个测试    //在这里应该基于XML布局的属性,子View的大小,ViewGroup实现的布局等来确定最后的大小!    setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), childrenHeight);}

最后看下onLayout方法源码

void layoutChildren(int left, int top, int right, int bottom){    final int count = getChildCount();    //child 初始left,top值    int childLeft = left + getPaddingLeft();    int childTop = top + getPaddingTop();    //遍历所有子View    for (int i = 0; i < count; i++)    {        final View child = getChildAt(i);        //这里所有的子View应该是已经被测量好了的!        int childRight = childLeft + child.getMeasuredWidth();        int childBottom = childTop + child.getMeasuredHeight();        //摆放View的具体位置        child.layout(childLeft, childTop, childRight, childBottom);        //下一个View的Left就是当前View的Right        childLeft = childRight;        childTop = childBottom;        }    }

1 0
原创粉丝点击