【问题标题】:Optimise a complex layout for an item displayed inside a RecyclerView优化 RecyclerView 中显示的项目的复杂布局
【发布时间】:2015-11-12 15:26:50
【问题描述】:

我必须在 RecyclerView 中显示来自 json 提要的帖子,并且我有一个布局,用于显示 RecyclerView 中单行的外观,如下所示

我还没有在我的实际布局中实现底部部分,其中包含上图中的红色和绿色框,我的布局看起来像这样

我还实现了 Swipe 以使用 undo 删除,如您所知,它需要 FrameLayout 作为 root ,以及它下面的 2 个节点,一个显示正常区域,一个显示滑动时显示的布局。在我的例子中,当我滑动项目时,你会看到这个。

现在的问题是,每行有 13 个视图,我不喜欢这样的可能性,我将在给定时间在 RecyclerView 中显示最多 100 个项目,如您所见,这会导致大量的意见。 我有一些方法可以制作自定义视图以减少行中的视图数量。根据您的说法,优化此视图的最佳方法是什么,或者我应该说,减少 RecyclerView 中每行的视图数量。我从 JSON 中获取所有数据,并且中心文本区域本质上需要可扩展,根据其状态使用 Read More 或 Read Less。

方法 1

稍微简化

在这种方法中,我会将左上角的人物头像、姓名和更新时间的 TextView 组合成一个自定义视图,换句话说,它将从 View 扩展,拥有自己的画布来绘制位图,字符串,但我必须在 Android 中使用 StaticLayout 手动编码 RTL 和 LTR 以及其他项目。我需要中心文本区域本质上是可扩展的,因此我将坚持使用每个人在 stackoverflow 上一直提到的可扩展视图之一。

方法 2

高度模块化的自定义 UI 组件。

整个图表由用户的图像、带有名称的文本、时间、中心文本和图像组成,可以做成一个单独的 CustomView,我不确定如何使它可扩展,因为一旦在 Android 中初始化的 StaticLayout 就不能修改的。你怎么看?这是正确的方法吗?如果我将整个事情变成一个单一的视图,我最终将每行只有 4 个孩子。这是自定义视图的有效用例吗?

【问题讨论】:

  • 我认为你低估了recyclerview。你的行项目对我来说似乎相当“高”,所以一次最多有 2-3 个可见。屏幕上永远不会有 100 * 13 个视图,因为 recyclerview 会按照它说的那样做......回收 :) 仍然,自定义视图布局可能对某些部分来说是个好主意
  • 我并没有以任何方式低估 recyclerview,我在滚动时仅显示 50 个项目,因此出现了问题。

标签: android android-layout android-recyclerview android-custom-view


【解决方案1】:

嗯,我自己找到了答案。我正在处理两种类型的帖子项目,一种包含用于显示 16:9 帖子图像的 ImageView,另一种不包含。到目前为止,我的 RecyclerView 在滚动操作中严重滞后,因为我有一个布局文件,其中有一个 ImageView,其宽度设置为 match_parent,高度设置为 wrap_content。当我滚动时,带有图像的帖子正在使用 Glide 加载图像并调用 requestLayout() 因为这些项目的大小正在改变。这导致过多的 requestLayout() 调用导致滚动时出现严重滞后。

我是如何解决这个问题的?

我制作了一个适配器,它被分成两种类型的行。

@Override
public int getItemViewType(int position) {
    if (mResults != null) {
        return mResults.get(position).getPicture() != null ? IMAGE : NO_IMAGE;
    }
    return NO_IMAGE;
}

根据当前位置的结果是否包含帖子中的图像,我修改了我的 onCreateViewHolder 方法,为 ImageView 设置预定义的大小,以防我的项目有帖子图像。

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view;
    if (viewType == IMAGE) {
        view = mLayoutInflater.inflate(R.layout.row_post_image, parent, false);
        RowImageHolder holder = new RowImageHolder(view);

        //To set the width and height of the ImageView of our image in the post, we get its LayoutParams and adjust its width and height to maintain 16:9 ratio
        ViewGroup.LayoutParams params = holder.mPostPicture.getLayoutParams();
        params.width = mPostImageWidth;
        params.height = mPostImageHeight;
        holder.mPostPicture.setLayoutParams(params);
        return holder;
    } else {
        view = mLayoutInflater.inflate(R.layout.row_post_image, parent, false);
        RowNoImageHolder holder = new RowNoImageHolder(view);
        return holder;
    }
}

这就是所有需要做的事情。如果项目的类型支持图像,则 onBindViewHolder 会设置图像。好处是预先为那些有图像的项目保留了空间,并且 RecyclerView 在滚动时的性能大大提高。到目前为止,我在没有使用任何自定义视图的情况下实现了这一点:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-09
    相关资源
    最近更新 更多