无法在自定义视图中正确添加子布局

时间:2019-07-01 09:16:38

标签: java android android-layout

我试图创建一个基本上是网格的自定义视图。行数和列数都是可变的。并且还提供了网格项。然后,在自定义视图中根据行和列,将网格项膨胀。然后onLayout发生子布局的定位。
我这样做遇到了问题。子布局未正确显示。当我在子布局中设置margin和padding(include_item.xlm)时,没有应用margin和padding。


截屏 (不允许通过 stackoverflow 附加图片) 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;

        }
    }


}

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>

用于 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>

子布局 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>

1 个答案:

答案 0 :(得分:2)

最后,我找到了解决方案。我必须先在onMesure中进行两项更改,然后在onlayout中进行更改。

修改后的 GridLayoutAutoMy.class

{{1}}