我有一个默认布局,在RecyclerView列表中包含大量空白CardView,基本上是一个欢迎屏幕,供用户向他们展示CardViews的外观。然后,用户启动某些数据的输入屏幕,然后单击“保存”按钮将数据保存到CardView中。用户单击“保存”后,布局应从具有空白CardView的默认布局更改为包含用户数据的新单个CardView。稍后,如果用户删除了所有的CardView,则视图应切换回默认的空白CardView。
我正在努力解决如何在onCreateViewHolder中设置适配器的代码,因为getItemCount()已经具有默认的正值(因为RecyclerView列表中已经有4或5个空白的CardViews)一旦用户创建了4个或5个CardView,就会发生相同的getItemCount()数量冲突。有关如何设置默认布局然后切换到新布局的任何想法,如果列表清空了用户创建的CardView,则可以恢复到默认布局?
以下是我在为适配器中的两个布局进行测试时失败的尝试。我意识到它不起作用,因为默认布局从未有过零的ItemCount,因为已经有4或5个空白的CardViews:
...
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);
}
}
答案 0 :(得分:2)
这是您可以遵循的方法:
为List项目(例如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中管理的相同List的引用(请参阅适配器构造函数)。例如,在您需要调用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点定义的List。重要的是重写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点报告的相同逻辑再填充它,然后在适配器上通知notifyDataSetChanged。