Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/189.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android-在RecyclerView中重新创建自定义动态生成的复合视图,导致性能低下_Android_Performance_Android Layout_Android View_Android Recyclerview - Fatal编程技术网

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

Android-在RecyclerView中重新创建自定义动态生成的复合视图,导致性能低下,android,performance,android-layout,android-view,android-recyclerview,Android,Performance,Android Layout,Android View,Android Recyclerview,我正在使用一个自定义的CompoundView,它扩展了LinearLayout来显示RecyclerView的项目。每个项目显示一篇包含多个段落和图像的文章 CompoundView根据CompoundView.setData(列表项)附加的数据动态添加TextView或ImageView,在附加数据之前,其数量未知 每个DataPiece对象告诉CompoundView它是文本还是图像。下面是CompoundView.setData(列表项): public void setData(列表项

我正在使用一个自定义的
CompoundView
,它扩展了
LinearLayout
来显示
RecyclerView
的项目。每个项目显示一篇包含多个段落和图像的文章
CompoundView
根据
CompoundView.setData(列表项)
附加的数据动态添加
TextView
ImageView
,在附加数据之前,其数量未知 每个
DataPiece
对象告诉
CompoundView
它是文本还是图像。下面是
CompoundView.setData(列表项)

public void setData(列表项){
移除所有视图();
用于(数据件数据件:件){
开关(dataPiece.getType()){
案例图像:
ImageView=newImageView(getContext());
...
addView(imageView);
打破
案例文本:
TextView TextView=newtextView(getContext());
...
addView(textView);
打破
}
}
}
RecyclerView.Adapter.onBindViewHolder()
中,通过调用
MyViewHolder.CompoundView.setData(…)
将数据附加到
CompoundView
。当创建
RecyclerView
时,它可以正常工作 但是,对于具有多个
ImageView
s和
TextView
s的
CompoundView
项目,当我滚动离开它然后向后滚动时,滚动会变得非常不平滑 我猜这是因为
setData()
中的
removeallview()
被调用,循环器再次执行
CompoundView
创建循环。但我不知道如何避免这种情况。 我还想知道为什么在
RecyclerView
中使用
TextView
(带图像)时,即使它也是循环使用的,滚动也总是平滑的。
提前谢谢

RecyclerView
应该重用视图。如果您扔掉已经创建的
TextView
/
ImageView
对象,每次都创建新的对象,则速度会很慢

听起来您需要一个具有多种视图类型的
RecyclerView
。我们的想法是创建多个视图持有者,其中一些具有
ImageView
,另一些具有
TextView
。您必须重写适配器的方法-它应该为图像项和文本项返回不同的值。将接收viewType参数,以便您知道要在其中创建哪种类型的ViewHolder。在中,您可以假设传递给您的保持架是正确的类型(即,对于文本项目,具有
TextView
的类型,对于图像项目,具有
ImageView
的类型),因此无需删除其子视图并再次创建它们


有一篇很好的文章介绍了RecyclerView的多视图适配器。

在决定最佳方法时,可能需要考虑多种因素

首先,你对回收商名单上的最大物品数量有什么想法?如果只是一小部分,也许您可以放弃
RecyclerView
方法,将
CompundView
添加到由
ScrollView
托管的容器中

第二,每个项目的布局是否相当复杂(也就是说,其中是否有许多
文本视图
图像视图
等)?如果是,也许您可以采取类似于
ExpandableListView
的方法—将摘要显示为每个列表项,并在单击时展开到该项的完整布局

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

公共类RecycleServiceAdapter扩展了RecyclerView.Adapter{
柱叶螨;
公共回收服务适配器(ArrayList项){
mItems=项目;
}
@凌驾
public RecyclerView.ViewHolder onCreateViewHolder(视图组父级,int-viewType){
CompoundView CompoundView=新的CompoundView();
List dataPieces=mItems.get(viewType);
对于(int i=0;icompoundView.getChildAt(j)如果您仅为要创建的
RecyclerView
列表使用自定义/复合
视图
,那么最好为一个列表项创建一个XML布局,然后使用
RecyclerView
的内置方法将数据添加到列表项中的
视图
中。@Farbod
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;
        }
    }
}
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);
        }
    }
}