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

    xiaoxiao2021-12-15  40

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


    索引

    onLayoutDemo


    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实现了如图所示的布局

    //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; } }
    转载请注明原文地址: https://ju.6miu.com/read-999984.html

    最新回复(0)