Android 优化显示在RecyclerView中的项目的复杂布局

Android 优化显示在RecyclerView中的项目的复杂布局,android,android-layout,android-recyclerview,android-custom-view,Android,Android Layout,Android Recyclerview,Android Custom View,我必须在RecyclerView中显示来自json提要的帖子,并且我有一个布局,用于显示RecyclerView中单个行的外观,如下所示 我还没有在我的实际布局中实现底部部分,它包含上图中的红色和绿色框,我的布局如下所示 我还使用undo实现了Swipe-to-delete,正如您所知,它需要一个FrameLayout作为根节点,并且在它下面有两个节点,一个显示普通区域,另一个显示在Swipe上显示的布局。在我的例子中,当我滑动项目时,这是您将看到的 现在的问题是,每行有13个视图,我不喜

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

我还没有在我的实际布局中实现底部部分,它包含上图中的红色和绿色框,我的布局如下所示

我还使用undo实现了Swipe-to-delete,正如您所知,它需要一个FrameLayout作为根节点,并且在它下面有两个节点,一个显示普通区域,另一个显示在Swipe上显示的布局。在我的例子中,当我滑动项目时,这是您将看到的

现在的问题是,每行有13个视图,我不喜欢这种可能性,我将在给定时间在RecyclerView中显示最多100个项目,正如您所看到的,这将导致大量视图。 我考虑了一些方法来创建自定义视图以减少行中的视图数量。您认为优化此视图的最佳方式是什么?或者我应该说,减少RecyclerView中每行的视图数。我从JSON获取所有数据,中心文本区域本质上需要可扩展,根据其状态增加或减少读取

方法1

略微简化

在这种方法中,我将把左上角的个人资料图片、带有姓名和更新时间的文本视图组合成一个单独的自定义视图,换句话说,它将从视图扩展,有自己的画布用于绘制位图、字符串,但我必须在安卓中使用StaticLayout手动编码RTL和LTR以及其他项目。我需要中心文本区域在本质上是可扩展的,所以我将坚持每个人都在stackoverflow上提到的一个可扩展视图

方法2

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


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

嗯,我自己找到了答案。我正在处理两种类型的帖子,一种是包含ImageView以显示16:9的帖子图片的帖子,另一种不是。到目前为止,我的RecyclerView在滚动操作中严重滞后,因为我有一个布局文件,其中有一个ImageView,其宽度设置为匹配父对象,高度设置为包裹内容。当我滚动时,带有图像的帖子使用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的性能大大提高。到目前为止,我没有使用任何自定义视图就实现了这一点:)

我认为您低估了recyclerview。您的行项目在我看来相当“高”,因此一次最多可以看到2-3个。屏幕上永远不会有100*13个视图,因为recyclerview是按照它说的那样做的…recycle:)不过,对于某些部分来说,自定义布局视图可能是一个很好的主意。我并没有以任何方式低估recyclerview,我在滚动时只显示了50个项目,这就是问题所在。