如何实现自定义View中的onLayout方法重写?

2026-04-29 20:082阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计692个文字,预计阅读时间需要3分钟。

如何实现自定义View中的onLayout方法重写?

前言:本文主要仿照鸿洋大神的Android+手把手教你自定义ViewGroup,效果图+布局文件+?xml version=1.0 encoding=utf-8?xmlns:android=http://schemas.android.com/apk/res/androidandroid:orientation=vertical>


如何实现自定义View中的onLayout方法重写?

前言:本文主要仿照鸿洋大神的Android 手把手教您自定义ViewGroup

效果图

布局文件

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="100dp" android:background="#003839" android:gravity="center" android:visibility="visible" android:text="SECOND"/> <com.pengkv.apple.weight.SecondView android:id="@+id/view_first" android:layout_width="200dp" android:visibility="visible" android:background="#888787" android:layout_height="200dp"> <TextView android:layout_width="50dp" android:layout_height="50dp" android:background="#FF4444" android:gravity="center" android:text="0" android:textColor="#FFFFFF" android:textSize="22sp" android:textStyle="bold" /> <TextView android:layout_width="50dp" android:layout_height="50dp" android:background="#00ff00" android:gravity="center" android:text="1" android:textColor="#FFFFFF" android:textSize="22sp" android:textStyle="bold" /> <TextView android:layout_width="50dp" android:layout_height="50dp" android:background="#ff0000" android:gravity="center" android:text="2" android:textColor="#FFFFFF" android:textSize="22sp" android:textStyle="bold" /> <TextView android:layout_width="50dp" android:layout_height="50dp" android:background="#0000ff" android:gravity="center" android:text="3" android:textColor="#FFFFFF" android:textSize="22sp" android:textStyle="bold" /> </com.pengkv.apple.weight.SecondView> </LinearLayout>

View代码

public class SecondView extends LinearLayout { public SecondView(Context context) { super(context); } public SecondView(Context context, AttributeSet attrs) { super(context, attrs); } public SecondView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // super.onMeasure(widthMeasureSpec,heightMeasureSpec); //父容器的宽、高 int widthMode=MeasureSpec.getMode(widthMeasureSpec); int heightMode=MeasureSpec.getMode(heightMeasureSpec); int widthSize=MeasureSpec.getSize(widthMeasureSpec); int heightSize=MeasureSpec.getSize(heightMeasureSpec); //计算出所有childView的宽、高 measureChildren(widthMeasureSpec,heightMeasureSpec); //用于记录子view所占的总宽、高 int width=0; int height=0; int childCount=getChildCount(); //用于记录单个子view的宽、高 int childWidth=0; int childHeight=0; //用于记录单个子view的外边距 MarginLayoutParams childParams=null; int leftHeight=0;//左边子view占据的高度 int rightHeight=0;//右边子view占据的高度 int topWidth=0;//上边子view占据的宽度 int bottomWidth=0;//下边子view占据的宽度 for (int i=0;i<childCount;i++){ //获取单个子view的宽高 View childView=getChildAt(i); childWidth=childView.getMeasuredWidth(); childHeight=childView.getMeasuredHeight(); childParams=(MarginLayoutParams)childView.getLayoutParams(); if (i == 0 || i == 1) { topWidth += childWidth + childParams.leftMargin + childParams.rightMargin; } if (i == 2 || i == 3) { bottomWidth += childWidth + childParams.leftMargin + childParams.rightMargin; } if (i == 0 || i == 2) { leftHeight += childHeight + childParams.topMargin + childParams.bottomMargin; } if (i == 1 || i == 3) { rightHeight += childHeight + childParams.topMargin + childParams.bottomMargin; } //取出子view所占据的最长宽高 width=Math.max(topWidth,bottomWidth); height=Math.max(leftHeight,rightHeight); //如果是wrap_content设置为我们计算的值,否则:直接设置为父容器计算的值 setMeasuredDimension((widthMode==MeasureSpec.EXACTLY)?widthSize:width,(heightMode==MeasureSpec.EXACTLY)?heightSize:height); } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int childCount=getChildCount(); int childWidth=0; int childHeight=0; MarginLayoutParams childParams=null; for (int i=0;i<childCount;i++){ View childView=getChildAt(i); childWidth=childView.getMeasuredWidth(); childHeight=childView.getMeasuredHeight(); childParams=(MarginLayoutParams)childView.getLayoutParams(); int childLeft=0,childTop=0,childRight=0,childBottom=0; switch (i){ case 0: childLeft=childParams.leftMargin; childTop=childParams.topMargin; break; case 1: childLeft=getWidth()-childWidth-childParams.leftMargin-childParams.rightMargin; childTop=childParams.topMargin; break; case 2: childLeft=childParams.leftMargin; childTop=getHeight()-childHeight-childParams.bottomMargin; break; case 3: childLeft=getWidth()-childWidth-childParams.leftMargin-childParams.rightMargin; childTop=getHeight()-childHeight-childParams.bottomMargin; break; } childRight=childLeft+childWidth; childBottom=childTop+childHeight; childView.layout(childLeft,childTop,childRight,childBottom);//放置view的位置 } } }


本文共计692个文字,预计阅读时间需要3分钟。

如何实现自定义View中的onLayout方法重写?

前言:本文主要仿照鸿洋大神的Android+手把手教你自定义ViewGroup,效果图+布局文件+?xml version=1.0 encoding=utf-8?xmlns:android=http://schemas.android.com/apk/res/androidandroid:orientation=vertical>


如何实现自定义View中的onLayout方法重写?

前言:本文主要仿照鸿洋大神的Android 手把手教您自定义ViewGroup

效果图

布局文件

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="100dp" android:background="#003839" android:gravity="center" android:visibility="visible" android:text="SECOND"/> <com.pengkv.apple.weight.SecondView android:id="@+id/view_first" android:layout_width="200dp" android:visibility="visible" android:background="#888787" android:layout_height="200dp"> <TextView android:layout_width="50dp" android:layout_height="50dp" android:background="#FF4444" android:gravity="center" android:text="0" android:textColor="#FFFFFF" android:textSize="22sp" android:textStyle="bold" /> <TextView android:layout_width="50dp" android:layout_height="50dp" android:background="#00ff00" android:gravity="center" android:text="1" android:textColor="#FFFFFF" android:textSize="22sp" android:textStyle="bold" /> <TextView android:layout_width="50dp" android:layout_height="50dp" android:background="#ff0000" android:gravity="center" android:text="2" android:textColor="#FFFFFF" android:textSize="22sp" android:textStyle="bold" /> <TextView android:layout_width="50dp" android:layout_height="50dp" android:background="#0000ff" android:gravity="center" android:text="3" android:textColor="#FFFFFF" android:textSize="22sp" android:textStyle="bold" /> </com.pengkv.apple.weight.SecondView> </LinearLayout>

View代码

public class SecondView extends LinearLayout { public SecondView(Context context) { super(context); } public SecondView(Context context, AttributeSet attrs) { super(context, attrs); } public SecondView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // super.onMeasure(widthMeasureSpec,heightMeasureSpec); //父容器的宽、高 int widthMode=MeasureSpec.getMode(widthMeasureSpec); int heightMode=MeasureSpec.getMode(heightMeasureSpec); int widthSize=MeasureSpec.getSize(widthMeasureSpec); int heightSize=MeasureSpec.getSize(heightMeasureSpec); //计算出所有childView的宽、高 measureChildren(widthMeasureSpec,heightMeasureSpec); //用于记录子view所占的总宽、高 int width=0; int height=0; int childCount=getChildCount(); //用于记录单个子view的宽、高 int childWidth=0; int childHeight=0; //用于记录单个子view的外边距 MarginLayoutParams childParams=null; int leftHeight=0;//左边子view占据的高度 int rightHeight=0;//右边子view占据的高度 int topWidth=0;//上边子view占据的宽度 int bottomWidth=0;//下边子view占据的宽度 for (int i=0;i<childCount;i++){ //获取单个子view的宽高 View childView=getChildAt(i); childWidth=childView.getMeasuredWidth(); childHeight=childView.getMeasuredHeight(); childParams=(MarginLayoutParams)childView.getLayoutParams(); if (i == 0 || i == 1) { topWidth += childWidth + childParams.leftMargin + childParams.rightMargin; } if (i == 2 || i == 3) { bottomWidth += childWidth + childParams.leftMargin + childParams.rightMargin; } if (i == 0 || i == 2) { leftHeight += childHeight + childParams.topMargin + childParams.bottomMargin; } if (i == 1 || i == 3) { rightHeight += childHeight + childParams.topMargin + childParams.bottomMargin; } //取出子view所占据的最长宽高 width=Math.max(topWidth,bottomWidth); height=Math.max(leftHeight,rightHeight); //如果是wrap_content设置为我们计算的值,否则:直接设置为父容器计算的值 setMeasuredDimension((widthMode==MeasureSpec.EXACTLY)?widthSize:width,(heightMode==MeasureSpec.EXACTLY)?heightSize:height); } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int childCount=getChildCount(); int childWidth=0; int childHeight=0; MarginLayoutParams childParams=null; for (int i=0;i<childCount;i++){ View childView=getChildAt(i); childWidth=childView.getMeasuredWidth(); childHeight=childView.getMeasuredHeight(); childParams=(MarginLayoutParams)childView.getLayoutParams(); int childLeft=0,childTop=0,childRight=0,childBottom=0; switch (i){ case 0: childLeft=childParams.leftMargin; childTop=childParams.topMargin; break; case 1: childLeft=getWidth()-childWidth-childParams.leftMargin-childParams.rightMargin; childTop=childParams.topMargin; break; case 2: childLeft=childParams.leftMargin; childTop=getHeight()-childHeight-childParams.bottomMargin; break; case 3: childLeft=getWidth()-childWidth-childParams.leftMargin-childParams.rightMargin; childTop=getHeight()-childHeight-childParams.bottomMargin; break; } childRight=childLeft+childWidth; childBottom=childTop+childHeight; childView.layout(childLeft,childTop,childRight,childBottom);//放置view的位置 } } }