简单的自定义ViewGroup
自定义ViewGroup需要重写onMeasure, onLayout等方法。下面是一个实例,4个View分别显示在四个角。
public class MyGroup extends ViewGroup{ private View viewA, viewB, viewC, viewD; public MyGroup(Context context) { this(context, null); } public MyGroup(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyGroup(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init(){ } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int sizeWidth = MeasureSpec.getSize(widthMeasureSpec); int sizeHeight = MeasureSpec.getSize(heightMeasureSpec); // 计算出所有的childView的宽和高 measureChildren(widthMeasureSpec, heightMeasureSpec); int totalW1 = 0, totalH1 = 0; int totalW2 = 0, totalH2 = 0; for(int i=0; i<getChildCount(); ++i){ View child = getChildAt(i); MarginLayoutParams params = (MarginLayoutParams)child.getLayoutParams(); int cw = child.getMeasuredWidth(), ch = child.getMeasuredHeight(); int lm = params.leftMargin, rm = params.rightMargin; int tm = params.topMargin, bm = params.bottomMargin; if(i == 0){ totalW1 += lm + cw + rm; totalH1 += tm + ch + bm; } else if(i == 1){ totalW1 += lm + cw + rm; totalH2 += tm + ch + bm; } else if(i == 2){ totalW2 += lm + cw + rm; totalH1 += tm + ch + bm; } else if(i == 3){ totalW2 += lm + cw + rm; totalH2 += tm + ch + bm; } } int width = Math.max(totalW1, totalW2); int height = Math.max(totalH1, totalH2); int targetWidth = sizeWidth; int targetHeight = sizeHeight; if(widthMode == MeasureSpec.AT_MOST){ targetWidth = width; } if(heightMode == MeasureSpec.AT_MOST){ targetHeight = height; } setMeasuredDimension(targetWidth, targetHeight); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { for(int i=0; i<getChildCount(); ++i){ View child = getChildAt(i); MarginLayoutParams params = (MarginLayoutParams)child.getLayoutParams(); int cw = child.getMeasuredWidth(); int ch = child.getMeasuredHeight(); int lm = params.leftMargin; int tm = params.topMargin; int rm = params.rightMargin; int bm = params.bottomMargin; if(i == 0){ child.layout(lm, tm, lm+cw, tm+ch); } else if(i == 1){ child.layout(getWidth()-rm-cw, tm, getWidth()-rm, tm+ch); } else if(i == 2){ child.layout(lm, getHeight()-bm-ch, lm+cw, getHeight()-bm); } else if(i == 3){ child.layout(getWidth()-rm-cw, getHeight()-bm-ch, getWidth()-rm, getHeight()-bm); } } } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { // return super.generateLayoutParams(attrs); return new MarginLayoutParams(getContext(), attrs); } @Override public void draw(Canvas canvas) { super.draw(canvas); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!