<resources> <declare-styleable name="CellLayout"> <attr name="columns" format="integer" /> <attr name="spacing" format="dimension" /> <attr name="layout_left" format="integer" /> <attr name="layout_top" format="integer" /> <attr name="layout_cellsWidth" format="integer" /> <attr name="layout_cellsHeight" format="integer" /> </declare-styleable> </resources>
public static class LayoutParams extends ViewGroup.LayoutParams { int top = 0; int left = 0; int width = 1; int height = 1; public LayoutParams(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CellLayout); left = a.getInt(R.styleable.CellLayout_layout_left, 0); top = a.getInt(R.styleable.CellLayout_layout_top, 0); height = a.getInt(R.styleable.CellLayout_layout_cellsHeight, -1); width = a.getInt(R.styleable.CellLayout_layout_cellsWidth, -1); a.recycle(); } public LayoutParams(ViewGroup.LayoutParams params) { super(params); if (params instanceof LayoutParams) { LayoutParams cellLayoutParams = (LayoutParams) params; left = cellLayoutParams.left; top = cellLayoutParams.top; height = cellLayoutParams.height; width = cellLayoutParams.width; } } public LayoutParams() { this(MATCH_PARENT, MATCH_PARENT); } public LayoutParams(int width, int height) { super(width, height); } }
public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { return new CellLayout.LayoutParams(getContext(), attrs); } protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { return p instanceof CellLayout.LayoutParams; } protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { return new CellLayout.LayoutParams(p); } protected ViewGroup.LayoutParams generateDefaultLayoutParams() { return new LayoutParams(); }
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int width = 0; int height = 0; if (widthMode == MeasureSpec.AT_MOST || widthMode == MeasureSpec.EXACTLY) { width = MeasureSpec.getSize(widthMeasureSpec); cellSize = (float) (getMeasuredWidth() - getPaddingLeft() - getPaddingRight()) / (float) columns; } else { cellSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_CELL_SIZE, getResources() .getDisplayMetrics()); width = (int) (columns * cellSize); } int childCount = getChildCount(); View child; int maxRow = 0; for (int i = 0; i < childCount; i++) { child = getChildAt(i); LayoutParams layoutParams = (LayoutParams) child.getLayoutParams(); int top = layoutParams.top; int w = layoutParams.width; int h = layoutParams.height; int bottom = top + h; int childWidthSpec = MeasureSpec.makeMeasureSpec((int) (w * cellSize) - spacing * 2, MeasureSpec.EXACTLY); int childHeightSpec = MeasureSpec.makeMeasureSpec((int) (h * cellSize) - spacing * 2, MeasureSpec.EXACTLY); child.measure(childWidthSpec, childHeightSpec); if (bottom > maxRow) { maxRow = bottom; } } int measuredHeight = Math.round(maxRow * cellSize) + getPaddingTop() + getPaddingBottom(); if (heightMode == MeasureSpec.EXACTLY) { height = MeasureSpec.getSize(heightMeasureSpec); } else if (heightMode == MeasureSpec.AT_MOST) { int atMostHeight = MeasureSpec.getSize(heightMeasureSpec); height = Math.min(atMostHeight, measuredHeight); } else { height = measuredHeight; } setMeasuredDimension(width, height); }
protected void onLayout(boolean changed, int l, int t, int r, int b) { int childCount = getChildCount(); View child; for (int i = 0; i < childCount; i++) { child = getChildAt(i); LayoutParams layoutParams = (LayoutParams) child.getLayoutParams(); int top = (int) (layoutParams.top * cellSize) + getPaddingTop() + spacing; int left = (int) (layoutParams.left * cellSize) + getPaddingLeft() + spacing; int right = (int) ((layoutParams.left + layoutParams.width) * cellSize) + getPaddingLeft() - spacing; int bottom = (int) ((layoutParams.top + layoutParams.height) * cellSize) + getPaddingTop() - spacing; child.layout(left, top, right, bottom); } }
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:cl="http://schemas.android.com/apk/res/com.evilduck.celllayout" android:layout_width="match_parent" android:layout_height="wrap_content" tools:ignore="HardcodedText" > <com.evilduck.celllayout.CellLayout android:id="@+id/cell_layout" android:layout_width="match_parent" android:layout_height="wrap_content" cl:columns="4" cl:spacing="1dp" tools:context=".MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" cl:layout_cellsHeight="1" cl:layout_cellsWidth="1" cl:layout_left="0" cl:layout_top="0" android:background="#00FF00" android:text="View 1" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" cl:layout_cellsHeight="1" cl:layout_cellsWidth="3" cl:layout_left="1" cl:layout_top="0" android:background="#FFFF00" android:text="View 2" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" cl:layout_cellsHeight="1" cl:layout_cellsWidth="1" cl:layout_left="1" cl:layout_top="1" android:background="#FFFFFF" android:text="View 3" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" cl:layout_cellsHeight="1" cl:layout_cellsWidth="1" cl:layout_left="0" cl:layout_top="1" android:background="#00FFF0" android:text="View 4" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" cl:layout_cellsHeight="1" cl:layout_cellsWidth="2" cl:layout_left="2" cl:layout_top="1" android:background="#00FA00" android:text="View 5" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" cl:layout_cellsHeight="2" cl:layout_cellsWidth="3" cl:layout_left="0" cl:layout_top="2" android:background="#AAFFAA" android:text="View 5" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" cl:layout_cellsHeight="2" cl:layout_cellsWidth="1" cl:layout_left="3" cl:layout_top="2" android:background="#45CCdd" android:text="View 6" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" cl:layout_cellsHeight="3" cl:layout_cellsWidth="1" cl:layout_left="0" cl:layout_top="4" android:background="#FF00FF" android:text="View 7" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" cl:layout_cellsHeight="3" cl:layout_cellsWidth="1" cl:layout_left="1" cl:layout_top="4" android:background="#FFFF00" android:text="View 8" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" cl:layout_cellsHeight="3" cl:layout_cellsWidth="1" cl:layout_left="2" cl:layout_top="4" android:background="#00FF00" android:text="View 9" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" cl:layout_cellsHeight="1" cl:layout_cellsWidth="1" cl:layout_left="3" cl:layout_top="4" android:background="#FFFF00" android:text="View 10" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" cl:layout_cellsHeight="1" cl:layout_cellsWidth="1" cl:layout_left="3" cl:layout_top="5" android:background="#FFFFFF" android:text="View 11" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" cl:layout_cellsHeight="1" cl:layout_cellsWidth="1" cl:layout_left="3" cl:layout_top="6" android:background="#555555" android:text="View 12" /> </com.evilduck.celllayout.CellLayout> </ScrollView>
Source: https://habr.com/ru/post/191842/
All Articles