Android-在RecyclerView中重新创建自定义动态生成的复合视图,导致性能不佳

Pro*_*tle 5 performance android android-layout android-view android-recyclerview

我正在使用自定义CompoundView扩展LinearLayout到显示的项目RecyclerView。每个项目都会显示一个包含多个段落和图像的文章。

所述CompoundView添加TextViewImageView动态地基于由附加数据CompoundView.setData(List<DataPiece> pieces),附接数据之前其数量是未知的。

每个DataPiece对象都告诉CompoundView它是文本还是图像。这是以下代码CompoundView.setData(List<DataPiece> pieces)

public void setData(List<DataPiece> pieces) {
    removeAllViews();
    for (DataPiece dataPiece : pieces) {
        switch (dataPiece.getType()) {
            case IMAGE:
                ImageView imageView = new ImageView(getContext());
                ...
                addView(imageView);
                break;
            case TEXT:
                TextView textView = new TextView(getContext());
                ...
                addView(textView);
                break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在中RecyclerView.Adapter.onBindViewHolder(),数据CompoundView通过调用附加到MyViewHolder.compoundView.setData(...)RecyclerView创建时,它工作正常。

但是,对于CompoundView具有多个ImageViews和TextViews的项目,当我滚动远离它然后向后滚动时,滚动会变得非常不平滑。

我猜这是因为removeAllViews()in setData()被调用了,而CompoundViewfor循环的创建又由回收者执行了。但是我不知道如何避免这种情况。

而且我也想知道TextViewRecyclerView即使在将其与图像一起使用的情况下,即使将其(与图像一起使用),滚动也总是很平滑。

提前致谢!

N.T*_*.T. 2

在决定什么是最佳方法时可能需要考虑多种因素。

首先,您知道回收商清单中的最大物品数量吗?如果只是少数,也许您可​​以放弃该RecyclerView方法,只需将其添加CompoundView到由ScrollView.

其次 - 每个项目的布局是否相当复杂(也就是其中有很多等等)TextViewsImageViews如果是,也许您可​​以采取类似于ExpandableListView- 将摘要显示为每个列表项并在单击时展开到该项目的完整布局的方法。

第三 - 如果以上都不可接受,并且您仍然想采用当前方法 - 不要在绑定方法中构造/添加您的视图。onCreateViewHolder当系统期望您构建视图时(我不确定,但是当您调用视图时,onBindViewHolder您的视图可能已经添加到层次结构中,并且对其进行的任何层次结构更改都会产生连锁反应),请在 中执行此操作对其容器的影响 - 但不要相信我的话,我实际上不知道视图已经添加,这只是一个假设)。您必须为每个项目分配不同的类型,以便onCreateViewHolder您可以将视图类型与支持数据相匹配(用于添加相应数量的子视图);每次都从头开始创建视图 - 这样您就不需要调用removeAllViews. 类似的东西(我遗漏了与案例无关的适配器部分):

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    ArrayList<DataPiecesList> mItems;
    public RecyclerViewAdapter(ArrayList<DataPiecesList> items) {
        mItems = items;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        CompoundView compoundView = new CompoundView();
        List<DataPiece> dataPieces = mItems.get(viewType);
        for (int i = 0; i < dataPieces.size(); i++)
        {
            // construct TextView or ImageView or whatever
            compoundView.add(child);
        }
        MyViewHolder view = new MyViewHolder(compoundView);
        return view;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) {
        CompoundView compoundView = viewHolder.itemView;
        DataPiece dataPiece = mItems.get(i);
        for (int j = 0; j < compoundView.getChildCount(); j++)
        {
            compoundView.getChildAt(j) <- dataPiece.get(j);
        }
    }

    @Override
    public int getItemViewType(int position) {
        return position;
    }

    @Override
    public int getItemCount() {
        return mItems.size();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        ...
        public MyViewHolder(View itemView) {
            super(itemView);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)