TableLayout 整齐堆叠宽度等分布局

需求

现有需求,按总宽度N等分,从左往右放置子布局,至最右处换下行继续,整体布局高度按照子布局高度逐级扩张。

Android 自带的 GridLayout 和 TableLayout都不够好用,就自己写了个,原理和StackLabel类似。

代码

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;

/**
 * Author: @Kongzue
 * Github: https://github.com/kongzue/
 * Homepage: http://kongzue.com/
 * Mail: [email protected]
 * CreateTime: 2019/4/24 15:51
 */
public class TableLayout extends ViewGroup {
    
    private int maxColumn = 2;
    private int itemMargin = 0;
    private int itemHeight = dp2px(150);
    
    private Context context;
    
    public TableLayout(Context context) {
        super(context);
        this.context = context;
        loadAttrs(context, null);
    }
    
    public TableLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        
        loadAttrs(context, attrs);
    }
    
    public TableLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        
        loadAttrs(context, attrs);
    }
    
    private void loadAttrs(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TableLayout);
        
        itemMargin = typedArray.getDimensionPixelOffset(R.styleable.TableLayout_marginDp, 0);
        itemHeight = typedArray.getDimensionPixelOffset(R.styleable.TableLayout_itemHeight, dp2px(150));
        maxColumn = typedArray.getInteger(R.styleable.TableLayout_column, 2);
        
        typedArray.recycle();
    }
    
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
    
    }
    
    private List items;
    private int newHeight = 0;
    
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        
        refreshViews();
        
        setMeasuredDimension(getMeasuredWidth(), newHeight);//设置宽高
    }
    
    private void refreshViews() {
        int maxWidth = getMeasuredWidth() + itemMargin;
        int itemWidth = maxWidth / maxColumn - itemMargin;
        
        items = new ArrayList<>();
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            if (child.getVisibility() == VISIBLE) {
                items.add(getChildAt(i));
            }
        }
        
        newHeight = 0;
        if (items != null && !items.isEmpty()) {
            int l = 0, t = 0, r = 0, b = 0;
            for (int i = 0; i < items.size(); i++) {
                View item = items.get(i);
                
                int mWidth = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);           //AT_MOST:先按照最大宽度计算,如果小于则按实际值,如果大于,按最大宽度
                int mHeight = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);         //UNSPECIFIED:不确定,根据实际情况计算
                item.measure(mWidth, mHeight);
                
                int childHeight = itemHeight;
                
                if (i != 0 && i % maxColumn == 0) {
                    l = 0;
                    t = t + childHeight + itemMargin;
                }
                
                r = l + itemWidth;
                
                b = t + childHeight;
                
                item.layout(l, t, r, b);
                
                l = l + itemWidth + itemMargin;
                
                newHeight = t + childHeight;
            }
        }
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }
    
    private int dp2px(float dpValue) {
        return (int) (0.5f + dpValue * Resources.getSystem().getDisplayMetrics().density);
    }
}

然后在res/values/新建attr.xml,内容如下



    
        
        
        
    

简单解释:marginDp 为间距,itemHeight为限制子布局高度值,column为每行几个(N等分)

使用



    


完事儿。

你可能感兴趣的:(TableLayout 整齐堆叠宽度等分布局)