Reputation: 76
I am trying to create a custom view which is basically a grid. No of rows and no of columns is variable. And the grid item is also supplied. Then in the custom view according to rows and columns, grid item is inflated. And onLayout the positioning of child layouts happens.
I am facing a problem in doing so. Child layout is not being correctly displayed. When I am setting the margin and padding in child layout ( include_item.xlm ), margin and padding are not being applied.
screenshot (not allowed to attach picture by stackoverflow) https://drive.google.com/file/d/1XFWs7o0aGxTFHzy4JVT3B7F6OlT5Q0W4/view?usp=sharing
GridLayoutMyAuto.java
1) no of row
2) no of column
3) reference of child layout
4) width_acc_height // width will be equal to height
5) height_acc_width // height will be equal to width
import android.content.Context;
import android.content.res.TypedArray;
import android.support.design.widget.CoordinatorLayout;
import android.util.AttributeSet;
import android.view.View;
public class GridLayoutMyAuto extends CoordinatorLayout {
private int row = 4;
private int column = 4;
private double childWidth;
private double childHeight;
private int child_layout;
private boolean width_acc_height = false, height_acc_width = false;
private View[][] grid;
public GridLayoutMyAuto(Context context) {
super(context);
}
public GridLayoutMyAuto(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public GridLayoutMyAuto(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
TypedArray typedArray = context
.obtainStyledAttributes(attrs, R.styleable.GridLayoutMyAuto);
row = typedArray.getInteger(R.styleable.GridLayoutMyAuto_row, 5);
column = typedArray.getInteger(R.styleable.GridLayoutMyAuto_column, 5);
child_layout = typedArray.getResourceId(R.styleable.GridLayoutMyAuto_child_layout,/*R.child_layout.include_item_2048*/-1);
width_acc_height = typedArray.getBoolean(R.styleable.GridLayoutMyAuto_width_acc_height, false);
height_acc_width = typedArray.getBoolean(R.styleable.GridLayoutMyAuto_height_acc_width, false);
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
inflate(context, child_layout, this);
}
}
typedArray.recycle();
}
public void resetLayout() {
requestLayout();
}
public int getRow() {
return row;
}
public int getColumn() {
return column;
}
public View[][] getGrid() {
return grid;
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int childCount = getChildCount();
int newHeight = row * (widthMeasureSpec / column);
if (width_acc_height == true) {
widthMeasureSpec = heightMeasureSpec;
} else if (height_acc_width == true) {
heightMeasureSpec = widthMeasureSpec;
}
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (child.getVisibility() != View.GONE) {
measureChild(child, widthMeasureSpec, heightMeasureSpec);
}
}
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean b, int left, int top, int right, int bottom) {
grid = new View[row][column];
childWidth = (right - left) / (column * 1.0);
childHeight = (bottom - top) / (row * 1.0);
int x;
int y = top;
int count = 0;
for (int i = 0; i < row; i++) {
x = left;
for (int j = 0; j < column; j++) {
View child = getChildAt(count++);
child.layout(x, y, (int) (x + childWidth), (int) (y + childHeight));
grid[i][j] = child;
x += childWidth;
}
y += childHeight;
}
}
}
values.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="GridLayoutMyAuto">
<attr name="row" format="integer" />
<attr name="column" format="integer" />
<attr name="child_layout" format="reference" />
<attr name="width_acc_height" format="boolean" />
<attr name="height_acc_width" format="boolean" />
</declare-styleable>
</resources>
used in content.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".Classic2048Activity"
tools:showIn="@layout/activity">
<suryapps.in.grid_layout_auto.GridLayoutMyAuto
android:id="@+id/gridLayoutAuto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:child_layout="@layout/include_item"
app:column="4"
app:height_acc_width="true"
app:row="4" />
</LinearLayout>
child layout include_item.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="8dp">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="2"
android:textColor="@color/colorPrimaryDark"
android:textSize="30sp" />
</android.support.v7.widget.CardView>
Upvotes: 2
Views: 94
Reputation: 76
Finally, I got the solution. I had to make two changes first in onMesure and sencond in onlayout.
Modified GridLayoutAutoMy.class
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
/**
* Modified by Surya Jeet Singh
*/
public class GridLayoutMyAuto extends CoordinatorLayout {
private int row = 4;
private int column = 4;
private double childWidth;
private double childHeight;
private int child_layout;
private boolean width_acc_height = false, height_acc_width = false;
private View[][] grid;
public GridLayoutMyAuto(Context context) {
super(context);
}
public GridLayoutMyAuto(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public GridLayoutMyAuto(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
TypedArray typedArray = context
.obtainStyledAttributes(attrs, R.styleable.GridLayoutMyAuto);
row = typedArray.getInteger(R.styleable.GridLayoutMyAuto_row, 5);
column = typedArray.getInteger(R.styleable.GridLayoutMyAuto_column, 5);
child_layout = typedArray.getResourceId(R.styleable.GridLayoutMyAuto_child_layout,/*R.child_layout.include_item_2048*/-1);
width_acc_height = typedArray.getBoolean(R.styleable.GridLayoutMyAuto_width_acc_height, false);
height_acc_width = typedArray.getBoolean(R.styleable.GridLayoutMyAuto_height_acc_width, false);
for (int i = 0; i < row; i++) {
for (int j = 0; j < column; j++) {
inflate(context, child_layout, this);
}
}
typedArray.recycle();
}
public void resetLayout() {
requestLayout();
}
public int getRow() {
return row;
}
public int getColumn() {
return column;
}
public View[][] getGrid() {
return grid;
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int childCount = getChildCount();
int newHeight = row * (widthMeasureSpec / column);
if (width_acc_height == true) {
widthMeasureSpec = heightMeasureSpec;
} else if (height_acc_width == true) {
heightMeasureSpec = widthMeasureSpec;
}
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
int padding = child.getPaddingLeft();
if (child.getVisibility() != View.GONE) {
measureChild(child, widthMeasureSpec / column - 2 * padding, heightMeasureSpec / row - 2 * padding);
}
}
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean b, int left, int top, int right, int bottom) {
grid = new View[row][column];
childWidth = (right - left) / (column * 1.0);
childHeight = (bottom - top) / (row * 1.0);
int x;
int y = top;
int count = 0;
for (int i = 0; i < row; i++) {
x = left;
for (int j = 0; j < column; j++) {
View child = getChildAt(count++);
int padding = child.getPaddingLeft();
// padding=18;
child.layout(x + padding, y + padding, (int) (x + childWidth) - padding, (int) (y + childHeight) - padding);
grid[i][j] = child;
x += childWidth;
}
y += childHeight;
}
}
}
Upvotes: 2