- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
问题总结
我在一个 Activity 中有一个 RecyclerView 列表,其中有一个 actionBar 按钮,用于在 LIST 和 GRID 布局之间切换 RecyclerView。
以 LIST 和 GRID 形式查看列表时,项目的布局是不同的。
查看 LIST 中的项目时,行格式为
|----|
|icon| Item Name
|----|
在 GRID 中查看项目时,行格式为
|--------------|
| large icon |
| |
| |
| |
|--------------|
Item Name
因此按照我看到的列表查看我的列表
|----|
|icon| Item1
|----|
|----|
|icon| Item2
|----|
|----|
|icon| Item3
|----|
|----|
|icon| Item3
|----|
当我以网格形式查看我的列表时,我看到了
|--------------| |--------------|
| large icon | | large icon |
| | | |
| | | |
| | | |
|--------------| |--------------|
Item1 Item2
|--------------| |--------------|
| large icon | | large icon |
| | | |
| | | |
| | | |
|--------------| |--------------|
Item3 Item4
当我使用 actionBar 按钮将 ListView 从 LIST 切换到 GRID 或从 GRID 切换到 LIST 时,某些 View 仍以其他样式的布局呈现。我相信您在切换之前滚动到视线之外的 View 会被回收和重用,而不是重新创建。
例如,如果我从 GRID 转到 LIST,我会看到
|--------------|
| large icon |
|----| | |
|icon| Item1 | |
|----| | |
|--------------|
Item2
|--------------| |--------------|
| large icon | | large icon |
| | | |
| | | |
| | | |
|--------------| |--------------|
Item3 Item4
后台代码信息
我有 2 个布局管理器;每种布局样式一个
private RecyclerView.LayoutManager linearLayoutManager;
private RecyclerView.LayoutManager gridLayoutManager;
在适配器中我存储我是将列表显示为网格还是列表
enum ListViewEnum{
LIST,
GRID
}
ListViewEnum listViewStyle = ListViewEnum.LIST;
public ListViewEnum getListStyle() {
return listViewStyle;
}
列表中项目的布局取决于列表是呈现为列表还是网格。
ViewHolderList
ViewHolderGrid
在创建 View 持有者时,我将 View 持有者的类型基于适配器 ListView 样式
protected RecyclerView.ViewHolder getItemViewHolder(ViewGroup parent){
if (listViewStyle == ListViewEnum.LIST){
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_row, parent, false);
return new ViewHolderList(itemView, ....);
} else {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.grid_row, parent, false);
return new ViewHolderGrid(itemView, ....);
}
}
当用户点击 actionBar 按钮时,我切换适配器的值
getListAdapter().setListViewMode(ListViewMode.LIST);
然后我刷新
listView.setLayoutManager(getListAdapter().getListStyle() == ListViewEnum.LIST ? linearLayoutManager : gridLayoutManager);
getListAdapter().notifyDataSetChanged();
listView.invalidateItemDecorations();
invalidateOptionsMenu();
我知道我正在刷新列表适配器,但它并没有放弃 recycledViews。调试显示,在单击切换按钮时,我看到某些位置(回收的位置)和“onCreateViewHolder”和“onBindViewHolder”(对于新位置)仅调用“onBindViewHolder”,因此表明旧 View 持有者正在被回收。
如何刷新列表,使其不会重复使用错误列表样式的 ViewHolder?
最佳答案
@Abbas 的评论是正确的,getItemViewType() 可能是您最好的选择。根据您的数据,您也许可以拥有一个持有人,但如果数据项不同,您可能必须创建两个。使用适配器内部的 getItemViewType() 调用来确定要显示的内容。您必须将标志从 Activity 传递到适配器或回调 Activity 以获取类型。
public static final int SMALL_VIEW = 0;
public static final int LARGE_VIEW = 1;
private int mType = 0;
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
RecyclerView.ViewHolder viewHolder = null;
// Create the Holders depending on the type, the view type
// will come from the getItemViewType() call.
switch ( viewType ) {
case SMALL_VIEW:
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_row, parent, false);
viewHolder = new ViewHolderList(mContext, v);
break;
case LARGE_VIEW:
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.grid_row, parent, false);
viewHolder = new ViewHolderGrid(mContext, v);
default:
}
return viewHolder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
// This switch may not be necessary if you are using
// the same holder for both items.
switch ( getItemViewType(position) ) {
case SMALL_ITEM:
ViewHolderList list = (ViewHolderList)holder;
list.setData(mData.get(position));
break;
case LARGE_ITEM:
ViewHolderGrid grid = (ViewHolderGrid)holder;
grid.setData(mData.get(position));
}
}
@Override
public int getItemViewType(int position) {
// Normally you identify the data type at position and
// switch the view, for your application you can switch
// for all.
return mType;
}
public void setViewType(int type) {
mType = type;
}
关于Android RecyclerView 切换布局(网格/列表)旧的 viewHolders 使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40106261/
如标题所示,ans_list是一个答案列表,ans_index是一个数字(答案在词汇表中的索引,但与atm无关) 这里生成的 tree.anslist 是什么? (例如,仅针对第一个),忽略迭代。 f
我目前将用户的输入存储在逗号分隔的列表中,如下所示: Userid | Options 1 | 1,2,5 用户在一个数组形式中勾选一组选项,然后用逗号连接起来 1,2,5 然后 MySQ
我目前将用户的输入存储在逗号分隔的列表中,如下所示: Userid | Options 1 | 1,2,5 用户在一个数组形式中勾选一组选项,然后用逗号连接起来 1,2,5 然后 MySQ
我想知道如何完全展平列表和包含它们的东西。除其他外,我想出了一个解决方案,它可以将具有多个元素的东西滑倒并将它们放回原处,或者在滑倒后将具有一个元素的东西拿走。 这与 How do I “flatte
我想知道如何完全展平列表和包含它们的东西。除其他外,我想出了一个解决方案,它可以将具有多个元素的东西滑倒并将它们放回原处,或者在滑倒后将带有一个元素的东西拿走。 这与 How do I “flatte
这个问题已经有答案了: Convert nested list to 2d array (3 个回答) 已关闭 7 年前。 java中有没有快捷方式可以转换 List> 到 String[][] ?
我在排序时遇到问题 List> 。我创建了一个自定义比较器,在其中编写了对数据进行排序的代码。 public class CustomComparator implements Comparator
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: Java Generics: Cannot cast List to List? 我只是想知道为什么下面的java代
试图想出一个 LINQy 方法来做到这一点,但我什么也没想到。 我有一个对象列表<>,其中包含一个属性,该属性是逗号分隔的字母代码列表: lst[0].codes = "AA,BB,DD" lst[1
假设我有这些任务: points = [] point = (1, 2) 我怎么会这样做: points += point 它工作得很好,并且给了我点 = [1, 2]。但是,如果我这样做: poin
如何在 scala 中将 List[Task[List[Header]]] 类型转换为 Task[List[Header]]。 我有一个方法返回 Task[List[Header]] 并多次调用 do
如何在 Java 中查找二维列表的元素? 我有一个参数为 List> 的函数我想知道如何找到这个列表的行和列。 最佳答案 如果你喜欢 List> obj 然后你就可以像这样访问 obj.get(cur
分配 List到 List工作正常。 分配 List>到 List>不编译。 代码 public class Main { public static void main(String[] a
我正在用 Java 编写一个方法,该方法必须接收并迭代 Serializable 的 List。 有什么区别: public void myMethod(List list) { } 和 public
我看到很多人想用 mvvm 更新网格/列表/树的一部分,但他们不想刷新整个列表。 对于所有遇到此问题的人,我做了以下示例。 希望这对你有用。 最佳答案 这是一个简单的例子。整个代码中最重要的是: Bi
我正在为现有的 C++ 库编写包装器,该库使用列表,其中 T 是自定义结构。我被建议使用 vector 而不是列表,但我试图避免修改库。 为了更好地理解这个场景,我做了一个简单的应用程序,使用一个列表
List list List list 这两种声明有什么区别吗? 谢谢, 最佳答案 是的。 List可以包含所有派生自 Base 的不同事物的混合物. List包含同质项(从某种意义上说,它们必须全部
有人可以尽可能详细地解释以下类型之间的区别吗? List List List 让我更具体一点。我什么时候想使用 // 1 public void CanYouGiveMeAnAnswer(List l
我有一个元组列表,每个元组都是一对列表。所以我的数据看起来像: mylist = [(['foo', 'bar'], ['bar', 'bar']),(['bar', 'bar'],['bar', '
也许是一个时髦的标题,但我遇到了以下问题: 给定一个类型为 (a * b) list 的列表,我想创建一个类型为 (a * b list) list 的新列表。一个例子: 给定列表 let testL
我是一名优秀的程序员,十分优秀!