使用 RecyclerView 时 notifydatasetchanged 调用 onCreateViewHolder
Does notifydatasetchanged call onCreateViewHolder when using RecyclerView
我想使用切换器在两个不同的视图之间切换,但使用相同的 RecyclerView
。基本上,一旦切换,我希望 RecyclerView
适配器重新调用 onCreateViewHolder()
,但这次它将使用不同的布局项文件。
notifydatasetchanged()
是否会导致适配器自行重建?或者有别的办法吗?
是的,它将假定其当前数据集无效,需要重新布局并重新绑定所有布局。
要删除和更新 RecyclerView
中的布局,您可以调用
mRecyclerView.removeView(view);
或
mRecyclerView.removeViewAt(position);
删除数据集中的对象后
notifyDataSetChanged()
在 RecyclerView
的情况下调用 onBindViewHolder()
我的 RecyclerView
Adapter
上的 View
也需要两种类型,一种用于 'regular' 模式,一种用于多 select模式。
因此,您可以覆盖 getItemViewType
以强制适配器为所有视图调用您的 onCreateViewHolder
。
将此添加到 Adapter
代码中:
public void setActionMode(ActionMode actionMode) {
this.actionMode = actionMode;
notifyDataSetChanged();
}
@Override
public int getItemViewType(int position) {
return (actionMode == null ? 0 : 1);
}
将此添加到 ViewHolder
:
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if (viewType == 0) {
view = inflater.inflate(R.layout.layout_1, parent, false);
} else {
view = inflater.inflate(R.layout.layout_2, parent, false);
}
...
}
由于您在 ActionMode
中 return 一个不同的 ViewType
,适配器被迫丢弃所有创建的视图,并重新创建所有内容。
我在这个问题上花了6个多小时没有成功。
最后!!!
我在适配器中设置了一个全局变量,每次将视图从列表切换到网格时都必须设置它(在我的例子中)。有趣的是,这种方法就在那里,但我忘了把它做成静态的!!所以我的解决方案可能与您的解决方案有关,请尝试一下,希望能成功。
public static int mCurrentViewType;
然后覆盖 getItemType()
@Override
public int getItemViewType(int position) {
return mCurrentViewType;
}
我的 toggleItemViewType 方法:
public void toggleItemViewType () {
if (mCurrentViewType == LIST_ITEM){
mCurrentViewType = GRID_ITEM;
} else {
mCurrentViewType = LIST_ITEM;
}
}
我正在从不同的 类 访问变量,这是不对的,但是现在为了 onCreateViewHolder 问题,它起作用了!
如果您有更好的解决方案,那么祝您好运并与我们分享。
不要忘记将全局变量设置为 "static" :)
最简单的解决方案
如果你想刷新 RecyclerView 项目并且 onCreateView()
也被调用,比如 Grid 和 List LayoutManager
s.
Kotlin
fun refreshRecyclerView(recyclerView:RecyclerView){
val adapterRef=recyclerView.adapter
recyclerView.adapter=null
recyclerView.adapter=adapterRef
}
Java
void refreshRecyclerView(RecyclerView recyclerView){
Adapter adapterRef=recyclerView.getAdapter();
recyclerView.setAdapter(null);
recyclerView.setAdapter(adapterRef);
}
我想使用切换器在两个不同的视图之间切换,但使用相同的 RecyclerView
。基本上,一旦切换,我希望 RecyclerView
适配器重新调用 onCreateViewHolder()
,但这次它将使用不同的布局项文件。
notifydatasetchanged()
是否会导致适配器自行重建?或者有别的办法吗?
是的,它将假定其当前数据集无效,需要重新布局并重新绑定所有布局。
要删除和更新 RecyclerView
中的布局,您可以调用
mRecyclerView.removeView(view);
或
mRecyclerView.removeViewAt(position);
删除数据集中的对象后
notifyDataSetChanged()
在 RecyclerView
onBindViewHolder()
我的 RecyclerView
Adapter
上的 View
也需要两种类型,一种用于 'regular' 模式,一种用于多 select模式。
因此,您可以覆盖 getItemViewType
以强制适配器为所有视图调用您的 onCreateViewHolder
。
将此添加到 Adapter
代码中:
public void setActionMode(ActionMode actionMode) {
this.actionMode = actionMode;
notifyDataSetChanged();
}
@Override
public int getItemViewType(int position) {
return (actionMode == null ? 0 : 1);
}
将此添加到 ViewHolder
:
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if (viewType == 0) {
view = inflater.inflate(R.layout.layout_1, parent, false);
} else {
view = inflater.inflate(R.layout.layout_2, parent, false);
}
...
}
由于您在 ActionMode
中 return 一个不同的 ViewType
,适配器被迫丢弃所有创建的视图,并重新创建所有内容。
我在这个问题上花了6个多小时没有成功。 最后!!! 我在适配器中设置了一个全局变量,每次将视图从列表切换到网格时都必须设置它(在我的例子中)。有趣的是,这种方法就在那里,但我忘了把它做成静态的!!所以我的解决方案可能与您的解决方案有关,请尝试一下,希望能成功。
public static int mCurrentViewType;
然后覆盖 getItemType()
@Override
public int getItemViewType(int position) {
return mCurrentViewType;
}
我的 toggleItemViewType 方法:
public void toggleItemViewType () {
if (mCurrentViewType == LIST_ITEM){
mCurrentViewType = GRID_ITEM;
} else {
mCurrentViewType = LIST_ITEM;
}
}
我正在从不同的 类 访问变量,这是不对的,但是现在为了 onCreateViewHolder 问题,它起作用了! 如果您有更好的解决方案,那么祝您好运并与我们分享。 不要忘记将全局变量设置为 "static" :)
最简单的解决方案
如果你想刷新 RecyclerView 项目并且 onCreateView()
也被调用,比如 Grid 和 List LayoutManager
s.
Kotlin
fun refreshRecyclerView(recyclerView:RecyclerView){
val adapterRef=recyclerView.adapter
recyclerView.adapter=null
recyclerView.adapter=adapterRef
}
Java
void refreshRecyclerView(RecyclerView recyclerView){
Adapter adapterRef=recyclerView.getAdapter();
recyclerView.setAdapter(null);
recyclerView.setAdapter(adapterRef);
}