自定义ViewGroup

简介

1、ViewGroup的职责是啥?
ViewGroup相当于一个放置View的容器,并且我们在写布局xml的时候,会告诉容器(凡是以layout为开头的属性,都是为用于告诉容器的),我们的宽度(layout_width)、高度(layout_height)、对齐方式(layout_gravity)等;当然还有margin等;于是乎,ViewGroup的职能为:给childView计算出建议的宽和高和测量模式 ;决定childView的位置;为什么只是建议的宽和高,而不是直接确定呢,别忘了childView宽和高可以设置为wrap_content,这样只有childView才能计算出自己的宽和高。

2、View的职责是啥?
View的职责,根据测量模式和ViewGroup给出的建议的宽和高,计算出自己的宽和高;同时还有个更重要的职责是:在ViewGroup为其指定的区域内绘制自己的形态。

在继承ViewGroup时有三个重要的方法,下面我们就来看看:

1、onLayout方法

protected void onLayout(boolean changed, int left, int top, int right, int bottom) {

}

在我们继承ViewGroup时会在除了构造函数之外提供这个方法,我们可以看到,在ViewGroup的源代码中方法是这样定义的,也就是父类没有提供方法的内容,需要我们自己实现。

当View要为所有子对象分配大小和位置时,调用此方法

2、addView方法

public void addView(View child) {
        addView(child, -1);
}

这个方法是用来想View容器中添加组件用的。我们可以使用这个方法想这个ViewGroup中添加组件。

3、getChildAt方法

public View getChildAt(int index) {
        try {
            return mChildren[index];
        } catch (IndexOutOfBoundsException ex) {
            return null;
        }
}

这个方法用来返回指定位置的View。

注意:ViewGroup中的View是从0开始计数的。

demo

布局文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:mystyle="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <com.my.administrator.zdyview.ZiDingYiGroup
        android:id="@+id/view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        mystyle:myview_background="@mipmap/meinv4"
        mystyle:myview_paintwidth="30dp">
        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#ffccff"
            android:text="开始" />
        <Button
            android:id="@+id/button2"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:background="#ffccff"
            android:text="开始" />
        <Button
            android:id="@+id/button3"
            android:layout_width="wrap_content"
            android:layout_height="300dp"
            android:background="#ffccff"
            android:text="开始" />
        <Button
            android:id="@+id/button4"
            android:layout_width="200dp"
            android:layout_height="150dp"
            android:background="#ffccff"
            android:text="开始" />
    </com.my.administrator.zdyview.ZiDingYiGroup>

接下来写一个类继承ViewGroup,在onLayout方法中对几个view的位置和大小进行设置

public class ZiDingYiGroup extends ViewGroup {
    private int width;
    private int height;
    //记得添加这两个构造器
    public ZiDingYiGroup(Context context) {
        super(context);
    }

    public ZiDingYiGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
        height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
        measureChildren(width, height);//测量
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        View child1 = getChildAt(0);
        View child2 = getChildAt(1);
        View child3 = getChildAt(2);
        View child4 = getChildAt(3);
        if(child1!=null){
            child1.layout(0,0,child1.getMeasuredWidth(),child1.getMeasuredHeight());//对每个view的设置是根据左上角坐标和右下角坐标确定的
        }
        if(child2!=null){
            child2.layout(r-child2.getMeasuredWidth(),0,r,child2.getMeasuredHeight());
        }
        if(child3!=null){
            child3.layout(0,b-child3.getMeasuredHeight(),child3.getMeasuredWidth(),b);
        }
        if(child4!=null){
            child4.layout(r-child4.getMeasuredWidth(),b-child4.getMeasuredHeight(),r,b);
        }
    }
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值