GridLayout 添加 customView 作为子问题,Android

GridLayout adding customView as a child issue, Android

我用 GridLayout 做了一个简单的时间表,看起来像这样

现在的想法是将所需的主题插入到特定的行和列中。为了实现这一点,我创建了一个扩展 CardView 的 class,我需要在其中插入 TextView。 代码: TimeTable.xml

<GridLayout 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"

    android:columnCount="8"
    android:columnOrderPreserved="true"
    android:rowCount="6"
    tools:context="com.digiart.schoolapp.fragments.TimetableFragment">


    <android.support.v7.widget.CardView
        android:id="@+id/timetable_card_space"

        android:layout_column="0"
        android:layout_columnSpan="1"
        android:layout_columnWeight="1"
        android:layout_row="0"
        app:cardElevation="2dp"
        app:contentPadding="5dp">

        <TextView
            android:id="@+id/timetable_dummy"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="time"
            android:textAppearance="@style/TextAppearance.AppCompat.Body1"
            android:visibility="invisible" />
    </android.support.v7.widget.CardView>

    <android.support.v7.widget.CardView
        android:id="@+id/timetable_day1_card"
        android:layout_column="1"
        android:layout_columnWeight="1"
        android:layout_row="0"
        app:cardElevation="2dp"
        app:contentPadding="5dp">

        <TextView
            android:id="@+id/timetable_day1_label"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Monday"
            android:textAppearance="@style/TextAppearance.AppCompat.Body2" />
    </android.support.v7.widget.CardView>

    .....
    ........
    <android.support.v7.widget.CardView
        android:id="@+id/timetable_time1_card"
        android:layout_column="0"
        android:layout_columnWeight="1"
        android:layout_row="1"
        app:cardElevation="2dp"
        app:contentPadding="5dp">

        <TextView
            android:id="@+id/timetable_time1_label"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="09.00"
            android:textAppearance="@style/TextAppearance.AppCompat.Body2" />
    </android.support.v7.widget.CardView>
    ..... 
    ......
   </GridLayout>

时间表主题:

public class TimetableSubject extends CardView {

    TextView subjectText;

    public TimetableSubject(Context context,int column,int row,int columnSpan,String subjectName) {
        super(context);

        GridLayout.LayoutParams subjectParam =new GridLayout.LayoutParams();
        subjectParam.columnSpec = GridLayout.spec(column,columnSpan);
        subjectParam.rowSpec = GridLayout.spec(row);

        subjectText = new TextView(context);
        CardView.LayoutParams textParams = new CardView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);
        subjectText.setText(subjectName);
        subjectText.setLayoutParams(textParams);

        setLayoutParams(subjectParam);
    }


}

现在我明白我需要做什么了,我需要将行和列传递给自定义视图,并将它们设置为布局参数。我认为问题出在布局参数代码上,我一定是搞砸了。谁能解释如何为这种情况正确设置布局参数?谢谢

您应该使用 TableLayout。在 TableLayout 中,您可以创建任意数量的行和列。浏览 TableLayout 文档并阅读行和列的概念。这是一个非常好的 table 布局教程。

这个tutorial对你也很有帮助。

规范中的 GridLayout 权重参数存在问题。通过在 Spec 中插入权重作为浮点参数来设法解决问题 代码:

public class TimetableSubjectView extends CardView {

    TextView subjectText;

    public TimetableSubjectView(Context context, int column, int row, float columnWeight, String subjectName, int color) {
        super(context);

        GridLayout.Spec rowI = GridLayout.spec(row,1,columnWeight);
        GridLayout.Spec colI = GridLayout.spec(column,1,columnWeight);

        GridLayout.LayoutParams subjectParam =new GridLayout.LayoutParams(rowI,colI);
        subjectParam.setMargins(5,5,5,5);

        setBackgroundColor(color);
        subjectText = new TextView(context);
        CardView.LayoutParams textParams = new CardView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);
        subjectText.setText(subjectName);
        subjectText.setGravity(Gravity.CENTER);
        subjectText.setLayoutParams(textParams);
        this.addView(subjectText);
        setLayoutParams(subjectParam);
    }


}

这是一张旧票,我知道它已被标记为已解决,但我将在这里留下我的经验。我遇到了一个有点类似的问题:我正在使用自定义视图 - 扩展 RelativeLayout - 在 GridLayout 内,我想创建一个包含两列和 N 行的网格(在我的情况下行无关紧要)。 我的自定义视图不想水平拉伸,占用 space 它们拥有的空间。 我试过支持库,Android X 版本的库, 重量, 重力 - none 其中有效。

原来GridLayout的参数设置没问题。我的自定义视图是问题所在。在我的例子中,不需要继承 a RelativeLayout,只需继承 a LinearLayout,你仍然可以在里面构建任何布局。

解决方案:

 <androidx.gridlayout.widget.GridLayout
                    android:id="@+id/grid"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="@dimen/activity_margin"
                    android:layout_marginEnd="@dimen/activity_margin"
                    app:columnCount="2">
    
                    <custom.MenuButtonGrid
                        android:id="@+id/item1"
                        app:abg_title="Title1"
                        app:layout_columnWeight="1"
                        app:layout_gravity="fill" />
    
                    <custom.MenuButtonGrid
                        android:id="@+id/item2"
                        app:abg_title="Title2"
                        app:layout_columnWeight="1"
                        app:layout_gravity="fill" />
    
                    <custom.MenuButtonGrid
                        android:id="@+id/item3"
                        app:abg_title="Title3"
                        app:layout_columnWeight="1"
                        app:layout_gravity="fill" />
    </androidx.gridlayout.widget.GridLayout>

执行MenuButtonGrid

/**
 * A component that creates a card view with an icon and texts.
 * They are designed to use as buttons.
 */
class MenuButtonGrid @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {

    private var binding =
        LayoutButtonGridViewBinding.inflate(LayoutInflater.from(context), this, true)

    init {
      // do whaterver you want in here
    }

}

layout_button_grid_view.xml里面:

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:cardUseCompatPadding="true">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="100dp">

        // Content doesn't matter here

    </RelativeLayout>

</com.google.android.material.card.MaterialCardView>