Reputation: 2243
I have a RecyclerView and successfully adapted some data. I have a problem. In the onBindViewHolder method, I am trying to add a custom view in a linear layout. The custom view is successfully added, but in scroll up or down views are duplicated. I want to add only once with items.
My code:
public class TrainsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public ArrayList<Train> trains;
public Context context;
private LayoutInflater inflater;
public OnItemClickListener mOnItemClickListener;
public void setmOnItemClickListener(OnItemClickListener mOnItemClickListener) {
this.mOnItemClickListener = mOnItemClickListener;
}
public class GenericViewHolder extends RecyclerView.ViewHolder {
public TextView stationName;
public LinearLayout vagoncontainer;
public GenericViewHolder(View view) {
super(view);
stationName = (TextView) view.findViewById(R.id.station_item_name);
vagoncontainer = (LinearLayout) view.findViewById(R.id.vagon_container);
}
}
public TrainsAdapter(Context context, ArrayList<Train> trains) {
this.context = context;
this.trains = trains;
inflater = LayoutInflater.from(context);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.trains_adapter_item, parent, false);
GenericViewHolder holder = new GenericViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
if (holder instanceof GenericViewHolder) {
GenericViewHolder genericViewHolder = (GenericViewHolder) holder;
Train train = trains.get(position);
ArrayList<Vagons> vagons = train.getVagons();
for (int i = 0; i < vagons.size(); i++) {
LayoutInflater layoutInflater = LayoutInflater.from(context);
LinearLayout vagonView = (LinearLayout) layoutInflater.inflate(R.layout.trains_vagon_child, null);
Button button = (Button) vagonView.findViewById(R.id.button);
if (vagons.get(i).getEnable().equals("1"))
button.setVisibility(View.VISIBLE);
else
button.setVisibility(View.GONE);
button.setText(vagons.get(i).getName() + " " + vagons.get(i).getAmount());
genericViewHolder.vagoncontainer.addView(vagonView);
}
genericViewHolder.stationName.setText(train.getDeparture());
}
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemCount() {
return trains.size();
}
public Train getItem(int position) {
return trains.get(position);
}
public interface OnItemClickListener {
void onItemClick(View view, int position);
}
}
How can I solve my problem?
Upvotes: 3
Views: 4463
Reputation: 2164
Basically RecyclerView reuses your viewHolder. So as per the RecyclerView doc here You have to reset the views everytime inside the onBindViewHolder()
method,
And based on this
but in scroll up or down views are dublicated.I want to add only one time with items
you need to removeAllViews
inside your vagonContainer
viewgroup
so your bind holder will look like
if (holder instanceof GenericViewHolder) {
GenericViewHolder genericViewHolder = (GenericViewHolder) holder;
Train train = trains.get(position);
ArrayList<Vagons> vagons = train.getVagons();
// this is very important. removing all view
genericViewHolder.vagoncontainer.removeAllViews();
......
Similar question here
Upvotes: 0
Reputation: 1520
This will fix your problem, but it is not effective (it won't be scrolling smoothly for trains with large amount of vagons - inflating Views is expensive), since you will be removing and recreating views in that LinearLayout
representing row in ListView
. Either reconsider your row layout or create some pseudo recyling in your row view.
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
if (holder instanceof GenericViewHolder) {
GenericViewHolder genericViewHolder = (GenericViewHolder) holder;
genericViewHolder.vagoncontainer.removeAllViews();
Train train = trains.get(position);
ArrayList<Vagons> vagons = train.getVagons();
for (int i = 0; i < vagons.size(); i++) {
LayoutInflater layoutInflater = LayoutInflater.from(context);
LinearLayout vagonView = (LinearLayout) layoutInflater.inflate(R.layout.trains_vagon_child, null);
Button button = (Button) vagonView.findViewById(R.id.button);
if (vagons.get(i).getEnable().equals("1"))
button.setVisibility(View.VISIBLE);
else
button.setVisibility(View.GONE);
button.setText(vagons.get(i).getName() + " " + vagons.get(i).getAmount());
genericViewHolder.vagoncontainer.addView(vagonView);
}
genericViewHolder.stationName.setText(train.getDeparture());
}
}
Upvotes: 1
Reputation: 4123
You can use core adapter
It's a simple lib to Support Any Type of items in recyclerview with no pain.
Upvotes: 0