gpt4 book ai didi

Android RecyclerView 切换布局(网格/列表)旧的 viewHolders 使用

转载 作者:搜寻专家 更新时间:2023-11-01 08:31:40 33 4
gpt4 key购买 nike

问题总结

我在一个 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/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com