Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.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_Android Recyclerview_Android Viewholder - Fatal编程技术网

Android 仅将RecyclerView中的视图动态添加到当前项

Android 仅将RecyclerView中的视图动态添加到当前项,android,android-recyclerview,android-viewholder,Android,Android Recyclerview,Android Viewholder,我在RecyclerView中动态地向我的项目添加视图。这些添加的视图应该只与它们添加到的项目相关,但我在滚动时遇到了一个问题。似乎视图被回收并加载了一个新项目,但以前添加的视图仍然存在,只是现在在错误的项目上 我假设这只是因为ViewHolder被重用,所以添加的项目在加载时会再次显示为一个新项目 如何解决这个问题?您需要根据备份数据跟踪添加了哪些视图。我可能会在onBindViewHolder()中添加任何必要的额外视图,并删除onViewRecycled()中可能存在的任何视图。然后,当您

我在
RecyclerView
中动态地向我的项目添加视图。这些添加的视图应该只与它们添加到的项目相关,但我在滚动时遇到了一个问题。似乎
视图
被回收并加载了一个新项目,但以前添加的视图仍然存在,只是现在在错误的项目上

我假设这只是因为
ViewHolder
被重用,所以添加的项目在加载时会再次显示为一个新项目


如何解决这个问题?

您需要根据备份数据跟踪添加了哪些视图。我可能会在
onBindViewHolder()
中添加任何必要的额外视图,并删除
onViewRecycled()中可能存在的任何视图。然后,当您希望动态显示一个时,更改跟踪它是否应可见的任何变量,并在每次执行“添加新视图”操作时调用
notifyItemChanged()

通过标记为具有新子项的项保存信息。(例如,在共享偏好中) 标记:使用BindViewHolder上的项目位置创建

...
SharedPreference  sharedPref = getSharedPreference("text" + position, context);
SharedPreference.Editor editor = sharedPref.edit();
editor.putString("view", "ImageView");
...
加载适配器时,获取此值并将默认值设置为null。 我不确定它的效率,但我会努力的

...
String viewType = sharedPref.getString("view", null);
//it will return ImageView 
如果您知道一些可能的视图类型,例如,始终将是ImageView和TextView,那么使用一些if语句就可以了

if(viewType.equals("ImageVIew")){
item(position).addView(new ImageVIew(context));
}
祝你好运

基于此:

但是那些以前添加的视图仍然存在,但是现在在错误的项目上

基本上,根据文档,每次在
onBindViewHolder()
方法中都必须重置视图

比如说,你有一个方法,如果它是你的个人资料,你可以设置一个视图参数,代码如下:

if (list.get(position).getId()==PreferenceManager.getUserID())
{
  // do some view change here
setViewParam(true);
}else
{
  // reset the view change here
setViewParam(false);
}
因此,您在这里所做的是给回收的ViewHolder一个重置的机会。
如果需要帮助,请发表评论

在您的
回收视图的适配器类中,
在
onBindViewHolder
方法中, 创建另一个适配器,并对新适配器执行相同的方法

层次结构将是

Main RecyclerView->item1(->ChildRecyclerServiceW1)、item2(->ChildRecyclerServiceW2)、item3(->ChildRecyclerServiceW3)


这样,您就可以实现您想要的功能,而不会在错误的项目上查看错误的值。

您可以使用此功能<代码>setItemViewCacheSize(整数大小)
在这里检查

屏幕外视图缓存可随时了解连接的适配器中的更改,从而允许LayoutManager重用未经修改的视图,而无需返回适配器重新绑定


您应该在子项布局
XML
中使用任何空布局,如
Linearlayout
,然后在滚动列表时,以这种方式将视图添加到特定项的
Linearlayout
中,您已添加到
Linearlayout
的所有子视图也与该项一起滚动。

首先,你能再分享一些代码吗

第二,为什么要动态添加新视图?为什么不使用不同的视图类型,或者只是将这些视图放在布局中,然后使它们可见/不可见或可见/消失?(我相信这样会更有效率)

让我来提醒你一些关于RecyclerView的事情,是的,当用户滚动时,viewHolder正在被重用(很少可以创建它们,甚至比填充屏幕所需的还要多)。因此,如果您在“item A”上添加了一些视图,并且用户滚动到“item Z”,那么该viewHolder可以重新用于该“item Z”,从而显示先前添加的视图

你怎么解决这个问题

如果您需要添加新视图,请始终检查每个项目;如果是,请在尚未添加视图的情况下添加它们;否则,请始终删除这些视图(如果存在)以返回到默认的viewHolder状态(或您所称的任何状态)


希望这能对你有所帮助。

这是我的老问题。它得到了赏金,因此人气激增,出现了许多新的和不相关的答案

正如我对原始问题下方的注释和@CQM的注释中所述,答案是覆盖
onViewRecycled()
方法并在那里执行任何必要的操作。回收视图时调用此方法,可以在此处执行任何清理操作

可以找到有关此方法的文档


在我的例子中,就是删除附加到视图的不可见的
TextView
。文本本身已被删除,但观点仍然存在。如果视图上累积了许多不可见的
TextView
,并且在滚动时没有正确回收,滚动将开始延迟。

因此我实现了
onViewRecycled
,目前正在循环浏览我添加新视图的版面中的所有子版面,然后通过
instanceof
检查它们是否是我需要删除的视图类型,如果是,则删除它们。是否有更简单的方法从视图组中删除所有类型的视图?还有,我不太清楚你最后一句话的意思。由于每个新视图的数据都包含在我的数据列表中,我当前正在
onBindViewHolder
中添加新视图。我不能仅仅切换视图的可见性,因为我正在动态添加它们。很遗憾没有代码。请共享您的适配器类代码只是想弄清楚您是在recyclerView中动态添加项目,还是在添加新视图并动态填充数据?@CQM对我的上述评论有任何回答吗?@AnuragSingh有,但我最终向onViewRecycled添加了代码,并在那里的viewholder上使用了“removeAllViews”。对任何相关的人来说,我对一个类似问题的回答应该是有帮助的,不要这样做。滚动时,您将非常快速地访问和存储共享首选项。