简单的自定义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);
    }
}
复制代码

 

posted @   丛林小阁楼  阅读(238)  评论(0编辑  收藏  举报
编辑推荐:
· 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 让容器管理更轻松!
点击右上角即可分享
微信分享提示