美文网首页
TableLayout 整齐堆叠宽度等分布局

TableLayout 整齐堆叠宽度等分布局

作者: kongzue | 来源:发表于2019-12-02 17:51 被阅读0次

    需求

    现有需求,按总宽度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: myzcxhh@live.cn
     * 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<View> 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,内容如下

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="TableLayout">
            <attr name="marginDp" format="dimension"/>
            <attr name="itemHeight" format="dimension"/>
            <attr name="column" format="integer"/>
        </declare-styleable>
    </resources>
    

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

    使用

    <yourPackage.TableLayout
        android:id="@+id/box_body"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginHorizontal="10dp"
        app:itemHeight="100dp"
        app:marginDp="10dp">
    
        <!--子布局-->
    
    </yourPackage.TableLayout>
    

    完事儿。

    相关文章

      网友评论

          本文标题:TableLayout 整齐堆叠宽度等分布局

          本文链接:https://www.haomeiwen.com/subject/sopfgctx.html