CellLayout网格绘制

 

public class CellLayout extends ViewGroup {
    private static final String TAG = "CellLayout";

    private int columCount = 3;
    private int space = 0;
    private boolean isSquareMode = false;
    private SparseIntArray rowMaxHeights = new SparseIntArray();

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

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

    public CellLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CellLayout);
        space = typedArray.getDimensionPixelSize(R.styleable.CellLayout_cellSpcing, 0);
        isSquareMode = typedArray.getBoolean(R.styleable.CellLayout_isSquareCell, true);
        columCount = typedArray.getInteger(R.styleable.CellLayout_columCount,3);
        typedArray.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //总宽度
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        Log.i(TAG, "widthSize: "+widthSize);
        //根据列数columCount和间隙space求出每个格子宽度
        int hs = space * (columCount - 1);
        Log.i(TAG, "hs: "+hs);
        int cellWidth = getCellWidth();
        Log.i(TAG, "cellWidth: "+cellWidth);
        int childCount = getChildCount();

        rowMaxHeights.clear();

        int rowMaxHeight = 0;
        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);
            LayoutParams layoutParams = child.getLayoutParams();
            layoutParams.width = cellWidth;
            if(isSquareMode){
                layoutParams.height = cellWidth;
            }
            //测量子view
            measureChild(child, widthMeasureSpec, heightMeasureSpec);

            int childMeasuredHeight = child.getMeasuredHeight();
            //保存子view宽高
            child.measure(getChildMeasureSpec(widthMeasureSpec, getPaddingLeft()+getPaddingRight(), cellWidth),
                    getChildMeasureSpec(heightMeasureSpec, 0, isSquareMode ? cellWidth : childMeasuredHeight));

            //记录每一行的最大高度
            if (!isSquareMode) {
                if (rowMaxHeight < childMeasuredHeight) {
                    rowMaxHeight = childMeasuredHeight;
                }
                //测量到一行的最后一个child保存该行的最大高度
                if ((i + 1) % columCount == 0 || i == childCount - 1) {
                    int height = rowMaxHeight;
                    rowMaxHeights.put(getRowIndex(i), height);
                    //换行了
                    rowMaxHeight = 0;
                }
            }
        }

        //总行高
        int totalRowHeight = 0;
        int rowCount = getRowCount();//行数
        if (isSquareMode) {
            totalRowHeight = rowCount * cellWidth;
        } else {
            for (int i = 0; i < rowMaxHeights.size(); i++) {
                totalRowHeight += rowMaxHeights.get(i);
            }
        }
        int heightSize = space * (rowCount - 1) + totalRowHeight+getPaddingTop()+getPaddingBottom();
        setMeasuredDimension(widthSize, heightSize);

    }

    /**
     * 获取行数
     */
    public int getRowCount() {
        return (int) Math.ceil(getChildCount() / (double) columCount);
    }

    /**
     * 获取child所在的行数
     * 从第0行算
     *
     * @param childIndex
     * @return
     */
    public int getRowIndex(int childIndex) {
        return (int) Math.ceil((childIndex + 1) / (double) columCount) - 1;
    }

    /**
     * 获取总列数
     *
     * @return
     */
    public int getColumCount() {
        return columCount;
    }

    /**
     * 获取每格宽度
     *
     * @return
     */
    public int getCellWidth() {
        return (getMeasuredWidth() - space * (columCount - 1)-getPaddingRight()-getPaddingRight()) / columCount;
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {

        int paddingLeft = getPaddingLeft();
        int paddingTop = getPaddingTop();
        int left = paddingLeft;
        int top = paddingTop;
        int cellWidth = getCellWidth();
        for (int i = 0; i < getChildCount(); i++) {

            View child = getChildAt(i);

            int height = isSquareMode?cellWidth:rowMaxHeights.get(getRowIndex(i));
            child.layout(left, top, left + cellWidth, top + (isSquareMode ? cellWidth : child.getMeasuredHeight()));
            if ((i + 1) % columCount == 0) {//换行了
                left = paddingLeft;
                top += height + space;
            } else {
                left += cellWidth + space;
            }
        }
    }

    public interface OnItemClickListener {
        void onItemClick(ViewGroup parent, View view, int position, long id);
    }

    @Override
    public void removeViewAt(int index) {
        super.removeViewAt(index);
        if (onItemClickListener != null) {
            setOnItemClickListener(onItemClickListener);
        }
    }

    private OnItemClickListener onItemClickListener;

    /**
     * 写个适配器简化一下添加view
     * 暂不支持回收
     * @param adapter
     */
    public void setAdapter(BaseAdapter adapter){
        if(adapter==null){
            return;
        }
        removeAllViews();
        for (int i = 0; i < adapter.getCount(); i++) {
            addView(adapter.getView(i,null,null));
        }

    }
    /**
     * Item的点击事件
     *
     * @param listener
     */
    public void setOnItemClickListener(final OnItemClickListener listener) {
        if (listener == null) {
            return;
        }
        this.onItemClickListener = listener;
        for (int i = 0; i < getChildCount(); i++) {
            final View child = getChildAt(i);
            final int position = i;
            child.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    listener.onItemClick(CellLayout.this, child, position, child.getId());
                }
            });
        }
    }
}

 

自定义属性

 

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CellLayout">
        <!--是否是正方形模式-->
        <attr name="isSquareCell" format="boolean"/>
        <!--各自之间的间隙-->
        <attr name="cellSpcing" format="dimension"/>
        <!--列数-->
        <attr name="columCount" format="integer"/>
    </declare-styleable>

</resources>

 

 

 

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"

    >





        <com.example.litsoft.celllayoutdome.CellLayout
            android:id="@+id/cellLayout"
            android:paddingBottom="5dp"
            android:background="#ffffff"
            android:paddingRight="5dp"
            android:paddingLeft="5dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"



            >




        <TextView

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:background="@color/colorAccent"

            android:gravity="center"

            android:text="1"

            android:textColor="#ffffff"

            android:textSize="18sp" />



        <TextView

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:background="@color/colorPrimary"

            android:gravity="center"

            android:text="2"

            android:textColor="#ffffff"

            android:textSize="18sp" />



        <TextView

            android:layout_width="0dp"

            android:layout_height="wrap_content"

            android:background="#e72094"

            android:gravity="center"

            android:text="3"

            android:textColor="#ffffff"

            android:textSize="18sp" />



        <TextView

            android:layout_width="0dp"

            android:layout_height="wrap_content"

            android:background="@color/colorAccent"

            android:gravity="center"

            android:text="4"

            android:textColor="#ffffff"

            android:textSize="18sp" />



        <TextView

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:background="@color/colorPrimary"

            android:gravity="center"

            android:text="5"

            android:textColor="#ffffff"

            android:textSize="18sp" />



        <TextView

            android:layout_width="0dp"

            android:layout_height="wrap_content"

            android:background="#e72094"

            android:gravity="center"

            android:text="6"

            android:textColor="#ffffff"

            android:textSize="18sp" />

        <TextView

            android:layout_width="0dp"

            android:layout_height="wrap_content"

            android:background="@color/colorAccent"

            android:gravity="center"

            android:text="7"

            android:textColor="#ffffff"

            android:textSize="18sp" />



        <TextView

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:background="@color/colorPrimary"

            android:gravity="center"

            android:text="8"

            android:textColor="#ffffff"

            android:textSize="18sp" />



        <TextView

            android:layout_width="0dp"

            android:layout_height="wrap_content"

            android:background="#e72094"

            android:gravity="center"

            android:text="9"

            android:textColor="#ffffff"

            android:textSize="18sp" />


        </com.example.litsoft.celllayoutdome.CellLayout>





</ScrollView>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦想不上班

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值