Android 自定义ViewGroup实现GridLayout

Android 自定义ViewGroup实现GridLayout

N长时间不写博客了,这次空下来赶紧写一篇压压惊,CSDN可以用markdown编辑了我也赶下时髦

  • 自定义ViewGroup
  • 重写onMeasure
  • 重写onLayout

这么久不更新确实是因为最近比较忙,最近应该会闲下来,希望能一星期出一篇博客,这样自己也可以把知识复习一遍,关于上一篇的仿QQ我看抽时间再写下篇吧,今天先带来一个简单的GridLayout效果的自定义ViewGroup

为什么自定义ViewGroup

相信大家项目中经常要用到网格布局,可能经常使用GridView,但是有些情况我们是不需要控件滚动的,4.0之前可能经常会用LinearLayout或者TabelLayout但是,这些都有一定的问题,4.0之后我们可以使用GridLayout 传送门,但是有些项目我们可能要支持更低的版本所以,自定义一个ViewGroup是一个不错的选择哦

自定义ViewGroup

  • 需求设定列宽
  • 自动换行

先上个最终效果图吧

继承ViewGroup重写关键方法

  • 重写onMeasure
  • 重写onLayout
名称 目的
onMeasure 测量子控件的大小并重新赋值
onLayout 子控件的排列

构造方法中获得具体的列数:

    private int mColumnCount;
    public WrhGridLayout(Context context) {
        this(context,null);
    }

    public WrhGridLayout(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public WrhGridLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.WrhGridLayout,defStyleAttr,0);
        mColumnCount = a.getInteger(R.styleable.WrhGridLayout_columnCount,0);

    }

重写onMeasure

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int childCount = getChildCount();
        //高度测量模式
        int childHeightMeasureSpec = 0;
        //宽度测量模式
        int childWidthMeasureSpec = 0;
        //测量子view并重新赋值
        for (int i=0;i<childCount;i++){
            View childView =getChildAt(i);
            measureChild(childView, widthMeasureSpec, heightMeasureSpec);
            childHeightMeasureSpec =
                    MeasureSpec.makeMeasureSpec(childView.getMeasuredHeight(), MeasureSpec.AT_MOST);
            childWidthMeasureSpec =  MeasureSpec.makeMeasureSpec(getMeasuredWidth()/mColumnCount, MeasureSpec.EXACTLY);
            childView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
        }
    }

获得控件大小并重新赋值

  • EXACTLY:一般是设置了明确的值或者是MATCH_PARENT
  • AT_MOST:表示子布局限制在一个最大值内,一般为WARP_CONTENT
  • UNSPECIFIED:表示子布局想要多大就多大,很少使用

重写onLayout

  @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int childCount = getChildCount();
        //光标
        int top = 0;
        int left = 0;
        for (int i=0;i<childCount;i++){
            View view = getChildAt(i);
            if (i==0){
            }
            else if (i%mColumnCount==0){
                left=0;
                top +=view.getMeasuredHeight();
            }else{
                left+=view.getMeasuredWidth();
            }
            //排列
            view.layout(left,top, left +view.getMeasuredWidth(),top + view.getMeasuredHeight());
        }
    }

排列子控件的位置,为0时自然是在第一个,剩下的就是宽度的累加以及到了需要换行的子View重新换行继续累加排列。。

测试

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

    <com.example.administrator.wrhgridlayout.WrhGridLayout
        wrh:columnCount="4"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="瞬间爆炸"
            />
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="瞬间爆炸"
            />   <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="瞬间爆炸"
        />   <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="瞬间爆炸"
        />   <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="瞬间爆炸"
        />   <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="瞬间爆炸"
        />   <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="瞬间爆炸"
        />   <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="瞬间爆炸"
        />   <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="瞬间爆炸"
        />   <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="瞬间爆炸"
        />   <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="瞬间爆炸"
        />   <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="瞬间爆炸"
        />   <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="瞬间爆炸"
        />   <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="瞬间爆炸"
        />   <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="瞬间爆炸"
        />   <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="瞬间爆炸"
        />   <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="瞬间爆炸"
        />   <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="瞬间爆炸"
        />

    </com.example.administrator.wrhgridlayout.WrhGridLayout>


</RelativeLayout>

效果同上图!
今天只是简单入门的自定义ViewGroup,以后我会逐步推进,包括监听一些手势完成一些很炫的效果!
谢谢,Bye

你可能感兴趣的:(android,自定义,GridView,重写,GridLayout)