问题
I am trying to refactor my ListView to RecyclerView and I stuck in this situation.
In my ListView Adapter i have something like this:
@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);
}
I don't have an idea how can I apply this to my RecyclerView adapter because I don't have access to the position in onCreateViewHolder method, where the layout should be inflated.
Here are the methods in my RecyclerView Adapter:
@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) {
}
Is there a way I can cope with it?
回答1:
Create Two View Holders for two Layouts
Follow these three simple steps
Override
getItemViewType(int position)
Return different ViewHolders based on the ViewType in
onCreateViewHolder()
methodPopulate View based on the itemViewType in
onBindViewHolder()
method (This solves the position problem you are facing)
Here is a small code snippet for RecyclerView Adapter
You can see the full code for reference 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:
In your Adapter
class put this
enum VIEW_TYPE {
VIEW1, VIEW2}
Then override getItemViewType(int position)
in the adapter and return VIEW_TYPE.VIEW1.ordinal()
or VIEW_TYPE.VIEW2.ordinal()
based on your logic with the given position
. And in the onCreateView
, you'll get the viewtype value. Based on that return a VieHolder
with the View
来源:https://stackoverflow.com/questions/47531755/how-to-inflate-different-layout-in-recyclerview-based-on-its-position-in-oncreat