Не удалось правильно добавить дочерний макет в пользовательском представлении

Я пытаюсь создать собственное представление, которое в основном представляет собой сетку. Количество строк и количество столбцов является переменным. И элемент сетки также поставляется. Затем в пользовательском представлении в соответствии со строками и столбцами элемент сетки увеличивается. А onLayout происходит позиционирование дочерних макетов.
Я столкнулся с проблемой при этом. Дочерний макет отображается неправильно. Когда я устанавливаю поля и отступы в дочернем макете ( include_item.xlm ), поля и отступы не применяются.


снимок экрана (не разрешено прикреплять изображение пользователем переполнение стека) https://drive.google.com/file/d/1XFWs7o0aGxTFHzy4JVT3B7F6OlT5Q0W4/view?usp=sharing


GridLayoutMyAuto.java

1) нет ряда
2) нет столбца
3) ссылка на дочерний макет
4) width_acc_height // ширина будет равна высоте
5) height_acc_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;

        }
    }


}

значения.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>

используется в содержание.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>

дочерний макет 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>

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
0
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Наконец, я получил решение. Мне пришлось внести два изменения: сначала в onMesure, а затем в onlayout.

Измененный 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;

        }
    }


}

Другие вопросы по теме