Reputation: 33
I have a RecyclerView adapter that inflates another layout (child_layout.xml
) into the main layout (main_layout.xml
).
Here is the RecyclerView adapter:
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
private static Context context;
private List<Message> mDataset;
public RecyclerAdapter(Context context, List<Message> myDataset) {
this.context = context;
this.mDataset = myDataset;
}
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener, View.OnClickListener {
public TextView title;
public LinearLayout placeholder;
public ViewHolder(View view) {
super(view);
view.setOnCreateContextMenuListener(this);
title = (TextView) view.findViewById(R.id.title);
placeholder = (LinearLayout) view.findViewById(R.id.placeholder);
}
}
@Override
public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.main_layout, parent, false);
ViewHolder vh = new ViewHolder((LinearLayout) view);
return vh;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Message item = mDataset.get(position);
holder.title.setText(item.getTitle());
int numImages = item.getImages().size();
if (numImages > 0) {
View inflater = LayoutInflater.from(holder.placeholder.getContext()).inflate(R.layout.child_layout, holder.placeholder, false);
ImageView image = (ImageView) inflater.findViewById(R.id.image);
Glide.with(context)
.load("http://www.website.com/test.png")
.fitCenter()
.into(image);
holder.placeholder.addView(inflater);
}
}
@Override
public int getItemCount() {
return mDataset.size();
}
}
Here is main_layout.xml
:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<LinearLayout
android:id="@+id/placeholder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
/>
<TextView
android:id="@+id/desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
Here is child_layout.xml
:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
The problem is, as I scroll through my app, some of the views are showing 2+ images (when the child_layout
only has one ImageView
):
https://i.sstatic.net/t4n2I.png
Why does this happen? Why do some views show more than one image when it should only be showing one?
Upvotes: 2
Views: 878
Reputation: 187
onBindViewHolder
is meant for binding data to the view you created in onCreateViewHolder
(hence the name). You shouldn't inflate a new view every time in onBindViewHolder
, because that takes away the large benefit of a RecyclerView
, namely view recycling. What's causing the issue currently is that you inflate and add a child to a main view every time onBindViewHolder
is called. This method can be called multiple times for a single view, meaning you're adding new child views every time it's called. You can fix this by only inflating the child view once inside onCreateViewHolder
. Your conditional check in the binding suggests you don't want it visible at all times. What you could do there is call setVisibility
on the child view to hide it if no images are present.
Upvotes: 2