[自定義控件系列2]--進階篇:可自動換行的ViewGroup

前言

上一篇文章介紹了簡單的自定義viewGroup怎麼實現
[自定義控件系列]–自定義viewGourp
下面我們介紹一個可以自動換行的Viewgroup,這是一個很常見的需求,先看一下實現效果。
這裏寫圖片描述
這裏寫圖片描述

具體實現

package com.example.king.kingcustomview;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import static android.R.attr.width;
import static android.view.View.MeasureSpec.getMode;

/**
 * Created by king on 2017/4/9.
 * 博客地址:http://blog.csdn.net/jinfulin
 */

public class kingAutoLinearLayout extends ViewGroup {
    private int parentWidth;
    private int parentHeight;
    private int parentautoHeight = 0;

    public kingAutoLinearLayout(Context context) {
        this(context, null);
    }

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

    public kingAutoLinearLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        //沒有用到的
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        parentWidth = MeasureSpec.getSize(widthMeasureSpec);
        parentHeight = MeasureSpec.getSize(heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        Log.e("king11",parentHeight+"========"+heightMode);
        for (int i = 0; i < getChildCount(); i++) {
            View childview = getChildAt(i);
            // 測量每一個child的寬和高
            measureChild(childview, widthMeasureSpec, heightMeasureSpec);
            int childHight = childview.getMeasuredHeight();
        }
       //如果高度是wrap_content設置爲我們計算的值
        //如果寬度是wrap_content我們設置爲match_parent
       //否則:直接設爲父控件值
        setMeasuredDimension(parentWidth,
                (heightMode == MeasureSpec.EXACTLY) ? parentHeight: parentautoHeight);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int childLeft = 0;
        int childTop = 0;
        int index =0;
        int maxHeight = 0 ;
        for (int i = 0; i < getChildCount(); i++) {
            View childview = getChildAt(i);
            //如果該控件是gone的,則不作位置擺放
            if (childview.getVisibility() == View.GONE) {
                continue;
            }
            // 得到子view的MarginLayoutParams,可以得到的margin等屬性
            MarginLayoutParams lp = (MarginLayoutParams) childview.getLayoutParams();

            int childWidth = childview.getMeasuredWidth();
            int childHeight = childview.getMeasuredHeight();

            int left = childLeft + lp.leftMargin;
            if (index==0) {
                childTop = lp.topMargin;
            }

            maxHeight = getMaxTop(maxHeight,childHeight+lp.topMargin+lp.bottomMargin);
            if (left + childWidth + lp.rightMargin > parentWidth) {
                //對left的處理
                childLeft = 0;
                left = lp.leftMargin;
                //對top的處理
                index++;
                childTop += maxHeight;
            }
            //獲取控件wrapContent時候的高度
            parentautoHeight = childTop+maxHeight;



            childview.layout(left, childTop, left + childWidth, childTop + childHeight);
            childLeft += childWidth + lp.rightMargin + lp.leftMargin;
        }
    }
    //獲取該行控件中最高的一個
    private int getMaxTop(int oldTop,int newtop){
        return Math.max(oldTop,newtop);
    }

    //要想使用子控件的margin
    //必須要實現這個方法,並且返回MarginLayoutParams
    @Override
    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new MarginLayoutParams(getContext(), attrs);
    }
}

引用

  <com.example.king.kingcustomview.kingAutoLinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            style="@style/text"
            android:text="aaa"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:text="bbb"
            style="@style/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:text="ccc"
            android:visibility="gone"
           style="@style/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:text="ccc"
            style="@style/text"
            android:layout_width="100dp"
            android:layout_height="wrap_content"/>
        <TextView
            android:text="ccc"
            style="@style/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:text="sssssssssssss"
            android:layout_marginLeft="10dp"
            android:paddingLeft="10dp"
            style="@style/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:layout_marginLeft="10dp"
            android:paddingLeft="10dp"
            android:text="aaa"
            style="@style/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:text="cccccc"
            style="@style/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:text="x"
            style="@style/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:text="xx"
            style="@style/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </com.example.king.kingcustomview.kingAutoLinearLayout>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章