我有一个默认布局,在 RecyclerView 列表中包含一堆空白 CardView,基本上是一个欢迎屏幕,供用户向他们展示 CardView 的外观。然后用户启动一些数据的输入屏幕并单击“保存”按钮将数据保存到 CardView 中。用户单击“保存”后,布局应从具有空白 CardView 的默认布局更改为包含用户数据的新的单个 CardView。稍后,如果用户删除了所有 CardView,则 View 应切换回默认的空白 CardView。
我正在努力解决如何在 onCreateViewHolder 中设置适配器的代码,因为 getItemCount() 已经有默认的正值(因为 RecyclerView 列表中已经有 4 或 5 个空白 CardView),这将一旦用户创建 4 或 5 个 CardView,稍后将与相同的 getItemCount() 数量发生冲突。关于如何设置默认布局然后切换到新布局的任何想法,如果列表清空了用户创建的 CardView,该布局可以恢复为默认布局?
下面是我在适配器中对两种布局进行布局测试的失败尝试。我意识到这是行不通的,因为默认布局的 ItemCount 从未为零,因为已经有 4 或 5 个空白 CardView:
...
public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.ContactViewHolder> {
private List<ContactInfo> contactList;
public ContactAdapter(List<ContactInfo> contactList) {
this.contactList = contactList;
}
@Override
public int getItemCount() {
return contactList.size();
}
@Override
public ContactViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
if(contactList.size()== 0) {
View itemView = LayoutInflater.
from(viewGroup.getContext()).
inflate(R.layout.defaultcard_layout, viewGroup, false);
return new ContactViewHolder(itemView);
}
else {
View itemView = LayoutInflater.
from(viewGroup.getContext()).
inflate(R.layout.singlecard_layout, viewGroup, false);
return new ContactViewHolder(itemView);
}
}
修改后的 Adapter 和 removeItem 代码:
...
private LayoutInflater mLayoutInflater;
private List<Contact> mContacts;
private OnItemTapListener mOnItemTapListener;
public ListContactsAdapter(Context context, List<Contact> contacts) {
Context mContext;
mContext = context;
mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mContacts = contacts;
}
public void removeItem(Contact contact, int position) {
mContacts.remove(contact);
if (mContacts.size()==0) {
// if no more contacts in list,
// we rebuild from scratch
mContacts.clear();
notifyDataSetChanged();
} else {
// else we just need to remove
// one item
mContacts.remove(position);
notifyItemRemoved(position);
}
}
最佳答案
这是您可以遵循的方法:
为列表项(例如 ListItem)定义一个专用的抽象类型来包装您的业务对象。它的实现可能是这样的:
public abstract class ListItem { public static final int TYPE_EMPTY = 0; public static final int TYPE_CONTACT = 1; abstract public int getType(); }
为每个 List 元素类型定义一个类:
public class EmptyItem { @Override public int getType() { return TYPE_EMPTY; } } public class ContactItem { private ContactInfo contact; // here getters and setters // for title and so on, built // using contact public ContactItem(ContactInfo info) { this.contact = info; } @Override public int getType() { return TYPE_CONTACT; } }
创建您的列表。在下面的逻辑中,我只是确保您始终至少有 5 个元素。如果您的联系人少于 5 个,将显示空布局。每次从外部 Activity 修改 contactList 时,即使在 mContactList 中也可以进行此类修改,因为适配器保留对在 Activity 中管理的相同列表的引用(请参阅适配器构造函数)。例如,如果您添加了一个新联系人,您只需调用
updateContactList
方法来更新您的 UI。List<ContactInfo> mContactList; List<ListItem> mItems; public ContactsAdapter(List<ContactInfo> contactList) { mContactList = contactList; mItems = buildContactsList(mContactList); } // Method for building ui list. private List<ContactItem> buildContactsList(List<ContactInfo> contactList) { List<ContactItem> list = new ArrayList<>(); for (ContactInfo contact : contactList) { list.add(ContactItem(contact)); } if (list.size() < 5) { for (int i=list.size(); i<5; i++) { list.add(EmptyItem()); } } } // Method for updating contact list, providing // a new one. Everything to be build from scratch. public void updateContactsList() { mItems.clear(); mItems.addAll(buildContactsList(mContactList)); notifyDataSetChanged(); }
为您的 RecyclerView 定义一个适配器,处理第 3 点定义的列表。这里重要的是重写 getItemViewType 方法,如下所示:
@Override public int getItemViewType(int position) { return mItems.get(position).getType(); }
然后你需要有两个布局和 ViewHolder 用于空项目和联系项目。适配器方法应该相应地处理这个问题:
@Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == ListItem.TYPE_EMPTY) { View itemView = mLayoutInflater.inflate(R.layout.defaultcard_layout, parent, false); return new EmptyViewHolder(itemView); } else { View itemView = mLayoutInflater.inflate(R.layout.singlecard_layout, parent, false); return new ContactViewHolder(itemView); } } @Override public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, final int position) { int type = getItemViewType(position); if (type == ListItem.TYPE_EMPTY) { EmptyItem header = (EmptyItem) mItems.get(position); EmptyViewHolder holder = (EmptyViewHolder) viewHolder; // your logic here... probably nothing to do since it's empty } else { ContactItem event = (ContactItem) mItems.get(position); ContactViewHolder holder = (ContactViewHolder) viewHolder; // your logic here } }
在 contactList
更新的情况下,您当然应该相应地更新 mItems
,方法是清理它,用第 3 点报告的相同逻辑再次填充它,然后在 Adapter 上通知 DataSetChanged .
关于Android:如何切换 RecyclerView 列表的布局?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34936863/