Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/185.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android:如何切换RecyclerView列表的布局?_Android_Android Layout_Android Recyclerview - Fatal编程技术网

Android:如何切换RecyclerView列表的布局?

Android:如何切换RecyclerView列表的布局?,android,android-layout,android-recyclerview,Android,Android Layout,Android Recyclerview,我有一个默认的布局,在一个RecyclerView列表中保存一堆空白的CardView,基本上是一个欢迎用户的屏幕,向他们展示CardView的样子。然后,用户启动一些数据的输入屏幕,并单击“保存”按钮将数据保存到CardView中。一旦用户单击“保存”,布局就应该从默认布局改变为空白的CabVIEW到包含用户数据的新的、单个的CabVIEW视图。稍后,如果用户删除了所有的CardView,则视图应切换回默认的空白CardView 我正在努力解决如何在onCreateViewHolder中设置适

我有一个默认的布局,在一个RecyclerView列表中保存一堆空白的CardView,基本上是一个欢迎用户的屏幕,向他们展示CardView的样子。然后,用户启动一些数据的输入屏幕,并单击“保存”按钮将数据保存到CardView中。一旦用户单击“保存”,布局就应该从默认布局改变为空白的CabVIEW到包含用户数据的新的、单个的CabVIEW视图。稍后,如果用户删除了所有的CardView,则视图应切换回默认的空白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);
    }
}
。。。
公共类ContactAdapter扩展了RecyclerView.Adapter{
私人名单联系人名单;
公共联系人适配器(列表联系人列表){
this.contactList=联系人列表;
}
@凌驾
public int getItemCount(){
返回contactList.size();
}
@凌驾
公共联系人ViewHolder onCreateViewHolder(视图组视图组,int i){
if(contactList.size()==0){
视图项视图=布局调整器。
来自(viewGroup.getContext())。
充气(R.layout.defaultcard\u布局,视图组,false);
返回新的ContactViewHolder(itemView);
}
否则{
视图项视图=布局调整器。
来自(viewGroup.getContext())。
充气(R.layout.singlecard_布局,视图组,false);
返回新的ContactViewHolder(itemView);
}
}
修订的适配器和拆卸项目代码:

...
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);
    }
}
。。。
私人停车场平面布置;
私人名单;
私人监听者监听监听者;
公共列表联系人适配器(上下文,列表联系人){
语境;
mContext=上下文;
mLayoutInflater=(LayoutInflater)mContext.getSystemService(Context.LAYOUT\u INFLATER\u SERVICE);
mContacts=触点;
}
公共无效删除项(联系人,内部位置){
mContacts.移除(触点);
如果(mContacts.size()==0){
//如果列表中没有更多联系人,
//我们从头开始重建
mContacts.clear();
notifyDataSetChanged();
}否则{
//否则我们只需要删除
//一项
mContacts.remove(位置);
已移除(位置)的项目;
}
}

这是您可以遵循的方法:

  • 为列表项(例如ListItem)定义一个专用的抽象类型,以包装业务对象。其实现可以如下所示:

    public abstract class ListItem {
    
        public static final int TYPE_EMPTY = 0;
        public static final int TYPE_CONTACT = 1;
    
        abstract public int getType();
    } 
    
  • 为每个列表元素类型定义一个类:

    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个,则将显示空的布局。每次您从外部活动修改联系人列表时,即使在mContactList中,也可以进行此修改,因为适配器保留对同一列表的引用在活动中管理(请参阅适配器构造函数)。例如,如果您添加了新联系人,则只需调用更新UI的
    updateContactList
    方法即可

    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();
    }
    
    然后,您需要为空项目和联系人项目提供两种布局和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
        }
    }
    

  • 如果更新了
    联系人列表
    ,您当然应该相应地更新
    mItems
    ,方法是清洁它,用第3点报告的相同逻辑再次填充它,然后在适配器上通知DatasetChanged。

    您应该实现方法getItemViewType。这应该返回2作为值,因为您需要处理两种不同类型的of视图。然后,您应该能够确定每个列表元素的类型,并将其用于构建布局。有关实现示例,请参阅。好的,我来看看。好的,让我知道这是否可行:为默认布局设置唯一的视图类型。然后,当用户单击“保存”创建新的CardView时,使用第二个布局。稍后,如果er删除第二个布局中的所有卡片视图,然后该视图类型的getItemCount()将为零,代码将切换到默认布局并刷新视图。我支持@TheTransrifles建议。因为两个布局的itemCount不同(首先你有4张、5张空卡片,然后只有一张上面有一些信息的卡片),您应该通过实现两种视图类型来区分这两种状态。将每种视图类型与不同的ViewHolder关联,例如第一个卡状态为EmptyCardViewHolder,然后是BigCardViewHolder的更好名称。请注意,在您发布的代码中,
    onCreateViewHolder的'int i'参数ode>实际上是一种视图类型,您可以使用它来决定返回哪个ViewHold…非常酷,谢谢。我会在接下来的几天晚上,当我有空闲时间时,尝试实现这种方法,然后再回来检查。好的,但第3点可能不合适。当用户第一次到达RecyclerView屏幕时,他们会看到默认布局是五张空白卡(使用CardView)。在他们单击工具栏上的“+”后,他们创建一张新的自定义卡,然后单击“保存”。然后我只想在RecyclerView屏幕(第二个布局)上显示他们的新单张卡。用户可以继续添加卡,布局将随新卡更新。
    
    @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
        }
    }