如何根据其在 onCreateViewHolder 方法中的位置在 RecyclerView 中膨胀不同的布局

Posted

技术标签:

【中文标题】如何根据其在 onCreateViewHolder 方法中的位置在 RecyclerView 中膨胀不同的布局【英文标题】:How to inflate different layout in RecyclerView based on its position in onCreateViewHolder method 【发布时间】:2018-05-11 22:05:58 【问题描述】:

我正在尝试将我的 ListView 重构为 RecyclerView,但我陷入了这种情况。

在我的 ListView 适配器中,我有这样的东西:

@Override
public int getItemViewType(int position) 
    if (mDecommissionMode && position == getCount() - 1)
        return 1;
    return 0;


@Override
public View getView(int position, View convertView, ViewGroup parent) 

    if (getItemViewType(position) == 0)
        return getNormalView(position, convertView, parent);
    else
        return getManualDecommissionView(convertView, parent);


我不知道如何将它应用到我的 RecyclerView 适配器,因为我无权访问 onCreateViewHolder 方法中的位置,在该位置应该膨胀布局。

这是我的 RecyclerView 适配器中的方法:

@Override
public DevicesItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) 
    DevicesRecyclerViewAdapter.DevicesItemViewHolder holder = new DevicesItemViewHolder(); //should pass some inflated view to ViewHolder instance
    holder.itemView.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View view) 
            mOnClickListener.onClick(view);
        
    );
    return holder;



@Override
public void onBindViewHolder(DevicesItemViewHolder holder, int position) 



有什么办法可以应付吗?

【问题讨论】:

How to create RecyclerView with multiple view type?的可能重复 你想控制 onBindViewHolder() 对吗? 【参考方案1】:

为两个布局创建两个视图持有者

遵循这三个简单的步骤

覆盖getItemViewType(int position)

根据中的ViewType返回不同​​的ViewHolders onCreateViewHolder()方法

根据onBindViewHolder()中的itemViewType填充视图 方法(这解决了你面临的位置问题)

这是 RecyclerView Adapter 的小代码 sn-p 完整代码可以参考Here

public class YourListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> 

private static final int LAYOUT_ONE= 0;
private static final int LAYOUT_TWO= 1;

@Override
public int getItemViewType(int position)

    if(position==0)
        return LAYOUT_ONE;
    else
        return LAYOUT_TWO;


@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) 


    View view =null;
    RecyclerView.ViewHolder viewHolder = null;

    if(viewType==LAYOUT_ONE)
    
        view = LayoutInflater.from(parent.getContext()).inflate(R.layout.one,parent,false);
        viewHolder = new ViewHolderOne(view);
    
    else
    
        view = LayoutInflater.from(parent.getContext()).inflate(R.layout.two,parent,false);
        viewHolder= new ViewHolderTwo(view);
    

    return viewHolder;


@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) 


    if(holder.getItemViewType()== LAYOUT_ONE)
    

    
    else 

        ViewHolderOne vaultItemHolder = (ViewHolderOne) holder;
        vaultItemHolder.name.setText(displayText);
        vaultItemHolder.name.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                .......
            
        );

    

     




public class ViewHolderOne extends RecyclerView.ViewHolder 

    public TextView name;
    
    public ViewHolderOne(View itemView) 
        super(itemView);
        name = (TextView)itemView.findViewById(R.id.displayName);
        
    


public class ViewHolderTwo extends RecyclerView.ViewHolder

    public ViewHolderTwo(View itemView) 
        super(itemView);
        
        ..... Do something
    


【讨论】:

【参考方案2】:

在你的 Adapter 类中放这个

enum VIEW_TYPE 
VIEW1, VIEW2

然后覆盖适配器中的getItemViewType(int position) 并根据您的逻辑返回VIEW_TYPE.VIEW1.ordinal()VIEW_TYPE.VIEW2.ordinal(),并使用给定的position。在onCreateView 中,您将获得viewtype 值。基于此返回 VieHolderView

【讨论】:

以上是关于如何根据其在 onCreateViewHolder 方法中的位置在 RecyclerView 中膨胀不同的布局的主要内容,如果未能解决你的问题,请参考以下文章

Recyclerview - OnCreateViewholder - 在某些情况下如何返回“null”

Recyclerview 不调用 onCreateViewHolder

离线时Recyclerview不调用onCreateViewHolder

在 PagedListAdapter 中未调用 onCreateViewHolder

Android - 在 onCreateViewHolder(..) 中将数据传递给 ViewHolder 构造函数

RecyclerView 一次为所有项目调用 onCreateViewHolder 和 onBindViewHolder