更改 GridLayoutManager 的布局

Change layout of GridLayoutManager

我想达到的目标:

我做了什么:

我有一个包含 1 到 5 列的按钮,当用户点击他想要的列数时,布局发生变化,但所有卡片都粘在一起。到目前为止,这是我能够做到的:https://imgur.com/a/CL4FZhY

我的商品:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/card"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <ImageView
        android:id="@+id/video_preview"
        android:layout_width="match_parent"
        android:layout_height="194dp"
        android:scaleType="centerCrop"
        tools:src="@drawable/img_error_v1"
        />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp">
        <TextView
            android:id="@+id/video_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?attr/textAppearanceHeadline6"
            android:maxLines="1"
            tools:text="This is a really really really really really really really really really really really long title"
            />
        <TextView
            android:id="@+id/video_description"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:maxLines="1"
            android:textAppearance="?attr/textAppearanceBody2"
            android:textColor="?android:attr/textColorSecondary"
            tools:text="This is the URL for now"
            />
    </LinearLayout>
</LinearLayout>

我的问题:

我怎样才能实现这种改变?我已经阅读了 ItemDecoration,但我认为我无法更改我的项目的 layout_height。我需要为每个列屏幕创建一个布局吗?

您可以通过动态更改列表项根的边距来实现此目的,您需要在适配器 onBindViewHolder() 函数中执行此操作

GridLayoutManager.LayoutParams params = (GridLayoutManager.LayoutParams) holder.card.getLayoutParams();
            if (position % 2 == 0) {
                params.setMargins(dpTopixel(20), dpTopixel(10), dpTopixel(10), dpTopixel(5));
            } else {
                params.setMargins(dpTopixel(10), dpTopixel(10), dpTopixel(20), dpTopixel(5));
            }
            holder.card.setLayoutParams(params);

这里是像素转dp的函数

private int dpTopixel(int dp) {
    float dip = (float) dp;
    Resources r = context.getResources();
    float px = TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP,
            dip,
            r.getDisplayMetrics()
    );
    return (int) px;
}

如果您对两个屏幕使用相同的适配器,那么您可以使用适配器的构造函数发送一个标志来阻止该代码

我不知道这是否是正确的解决方案,但这 article 帮助我根据列数更改视图的布局。

  • 缺点是我需要为每个要显示的列布局创建不同的布局。
  • 好处是我可以更好地控制每个布局的项目,我可以修改文本大小或其他任何内容。

因为它有点长,我创建了一个 repo 来展示我是如何做到的。

可能会有一些改进,如果有任何帮助,我们将不胜感激:)