繁体   English   中英

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

[英]Not able to add child layout correctly in Custom View

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


屏幕截图(不允许通过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;

        }
    }


}

值.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>

最后,我得到了解决方案。 我必须首先在 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;

        }
    }


}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM