返回

RecyclerView WRAP_CONTENT 高度调整技巧

Android

如何在 RecyclerView 中实现 WRAP_CONTENT

问题

当你希望一个包含 RecyclerView(卡片列表)的 DialogFragment 拥有根据其包含的 CardView 正确的高度时,你会遇到一个问题。通常,这可以通过在 RecyclerView 上设置 wrap_content 来轻松实现,但由于 RecyclerView 的嵌套性质,这在某些情况下会失效。

解决方案

为了解决这个问题,我们需要自定义一个 LinearLayoutManager 并重写其 onMeasure() 方法,以便手动计算 RecyclerView 的高度。

自定义 LinearLayoutManager

创建以下自定义 LinearLayoutManager 类:

public class WrappingLayoutManager extends LinearLayoutManager {

    private int[] mMeasuredDimension = new int[2];

    @Override
    public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state,
                          int widthSpec, int heightSpec) {
        // 省略代码
    }

    private void measureScrapChild(// 省略代码) {
    }
}

应用自定义 LinearLayoutManager

在你的 RecyclerView 中使用自定义 LinearLayoutManager

<android.support.v7.widget.RecyclerView
    // 省略代码
    android:layoutManager="com.example.WrappingLayoutManager" />

其他注意事项

  • 此自定义 LinearLayoutManager 可能存在滚动和计算包含换行文本的 TextView 高度方面的问题。
  • 要改善这种情况,可以使用更高级的自定义 RecyclerView 布局,例如 StaggeredGridLayoutManager 或 FlexboxLayoutManager。

常见问题解答

1. 为什么不能直接在 RecyclerView 上设置 wrap_content 来实现这一目标?

由于 RecyclerView 的嵌套性质,在某些情况下,它不能正确计算其子元素的高度。

2. 自定义 LinearLayoutManager 的目的是什么?

自定义 LinearLayoutManager 允许我们手动计算 RecyclerView 的高度,以解决上述问题。

3. 为什么在自定义 LinearLayoutManager 中需要测量废弃的子项?

测量废弃的子项是为了获得子元素的测量信息,以便我们计算 RecyclerView 的总体高度。

4. 此解决方案是否适用于所有类型的 RecyclerView 布局?

此解决方案主要适用于线性布局,对于更复杂的布局,可能需要更高级的自定义 RecyclerView 布局。

5. 有什么替代方案可以实现 RecyclerView 的 WRAP_CONTENT?

除了使用自定义 LinearLayoutManager 之外,还可以使用第三方库或手动测量子元素的高度并使用 Adapter 中的 getItemViewType() 方法来设置 RecyclerView 的高度。