滚动时如何重置 RecyclerView Viewholder 布局
How to reset RecyclerView Viewholder layout when scrolling
我在 RecyclerView
适配器中使用 Viewholder
,我在其中动态创建 ImageView。但是,当我向下滚动并向上滚动时,新图像会显示在之前图像的顶部。我知道这是回收的概念,但我如何 reset/clear Viewholder
/layout 使旧的 ImageViews
不会出现在每个回收视图中?
public class RallyAdapter extends RecyclerView.Adapter<RallyAdapter.ViewHolder> {
public static class ViewHolder extends RecyclerView.ViewHolder{
public TextView nameTextView;
public TextView dateTextView;
public TextView creatorTextView;
public ImageButton thumbnail;
public RelativeLayout relativeLayout;
public ViewHolder(View itemView) {
super(itemView);
relativeLayout = (RelativeLayout) itemView.findViewById(R.id.view);
nameTextView = (TextView) itemView.findViewById(R.id.name);
dateTextView = (TextView) itemView.findViewById(R.id.date);
thumbnail = (ImageButton) itemView.findViewById(R.id.imageButton);
creatorTextView = (TextView) itemView.findViewById(R.id.creator_name);
}
}
private ArrayList<Rally> mRallys;
private Context mContext;
public RallyAdapter(Context context, ArrayList<Rally> rallys) {
this.mRallys = rallys;
this.mContext = context;
}
// Usually involves inflating a layout from XML and returning the holder
@Override
public RallyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
// Inflate the custom layout
View rallyView = inflater.inflate(R.layout.rally, parent, false);
// Return a new holder instance
ViewHolder viewHolder = new ViewHolder(rallyView);
return viewHolder;
}
// Involves populating data into the item through holder
@Override
public void onBindViewHolder(RallyAdapter.ViewHolder viewHolder, final int position) {
// Get the data model based on position
final Rally rally = mRallys.get(position);
// Set item views based on the data model
TextView nameTV = viewHolder.nameTextView;
nameTV.setText(rally.getName());
TextView dateTV = viewHolder.dateTextView;
dateTV.setText(rally.getStartDate());
ImageButton imageButton = viewHolder.thumbnail;
TextView creatorTV = viewHolder.creatorTextView;
creatorTV.setText(rally.getCreator_name());
Picasso.with(mContext).load(rally.getThumbnail()).fit().centerCrop().into(imageButton);
List<String> image_urls = rally.getTransportationImgs();
List<String> methods = rally.getTransportationStrs();
ArrayList<ImageView> IMGS = new ArrayList<ImageView>();
for (int i = 0; i < methods.size(); i++) {
String method = methods.get(i);
for (int j = 0; j < image_urls.size(); j++) {
String img_url = image_urls.get(j);
if (img_url.toLowerCase().contains(method.toLowerCase()) == true) {
ImageView image = new ImageView(mContext);
dateTV = viewHolder.dateTextView;
imageButton = viewHolder.thumbnail;
image.setId(generateViewId());
IMGS.add(image);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
if (IMGS.size() > 1) {
params.addRule(RelativeLayout.RIGHT_OF, IMGS.get(IMGS.size() - 1).getId());
params.addRule(RelativeLayout.ALIGN_TOP, IMGS.get(IMGS.size() - 1).getId());
params.addRule(RelativeLayout.END_OF, IMGS.get(IMGS.size() - 1).getId());
} else {
params.addRule(RelativeLayout.RIGHT_OF, imageButton.getId());
params.addRule(RelativeLayout.BELOW, dateTV.getId());
params.addRule(RelativeLayout.END_OF, imageButton.getId());
}
params.height = 65;
params.width = 65;
image.setLayoutParams(params);
viewHolder.relativeLayout.addView(image);
//viewHolder.relativeLayout.addView(rallyLayout);
Picasso.with(mContext).load(img_url).fit().centerCrop().into(image);
}
}
}
}
以下是视图在加载时的样子。
滚动了一下后...
我认为您需要 LinearLayout
在 for 循环之前按住图标并清除它:
viewHolder.linearLayout.removeAllViews();
因为我刚刚遇到了类似的问题,如果您在 onBindViewHolder() 中设置了很多样式,那么覆盖 onViewRecycled() 以及将视图恢复到其原始状态可能会有所帮助...
我在 RecyclerView
适配器中使用 Viewholder
,我在其中动态创建 ImageView。但是,当我向下滚动并向上滚动时,新图像会显示在之前图像的顶部。我知道这是回收的概念,但我如何 reset/clear Viewholder
/layout 使旧的 ImageViews
不会出现在每个回收视图中?
public class RallyAdapter extends RecyclerView.Adapter<RallyAdapter.ViewHolder> {
public static class ViewHolder extends RecyclerView.ViewHolder{
public TextView nameTextView;
public TextView dateTextView;
public TextView creatorTextView;
public ImageButton thumbnail;
public RelativeLayout relativeLayout;
public ViewHolder(View itemView) {
super(itemView);
relativeLayout = (RelativeLayout) itemView.findViewById(R.id.view);
nameTextView = (TextView) itemView.findViewById(R.id.name);
dateTextView = (TextView) itemView.findViewById(R.id.date);
thumbnail = (ImageButton) itemView.findViewById(R.id.imageButton);
creatorTextView = (TextView) itemView.findViewById(R.id.creator_name);
}
}
private ArrayList<Rally> mRallys;
private Context mContext;
public RallyAdapter(Context context, ArrayList<Rally> rallys) {
this.mRallys = rallys;
this.mContext = context;
}
// Usually involves inflating a layout from XML and returning the holder
@Override
public RallyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
// Inflate the custom layout
View rallyView = inflater.inflate(R.layout.rally, parent, false);
// Return a new holder instance
ViewHolder viewHolder = new ViewHolder(rallyView);
return viewHolder;
}
// Involves populating data into the item through holder
@Override
public void onBindViewHolder(RallyAdapter.ViewHolder viewHolder, final int position) {
// Get the data model based on position
final Rally rally = mRallys.get(position);
// Set item views based on the data model
TextView nameTV = viewHolder.nameTextView;
nameTV.setText(rally.getName());
TextView dateTV = viewHolder.dateTextView;
dateTV.setText(rally.getStartDate());
ImageButton imageButton = viewHolder.thumbnail;
TextView creatorTV = viewHolder.creatorTextView;
creatorTV.setText(rally.getCreator_name());
Picasso.with(mContext).load(rally.getThumbnail()).fit().centerCrop().into(imageButton);
List<String> image_urls = rally.getTransportationImgs();
List<String> methods = rally.getTransportationStrs();
ArrayList<ImageView> IMGS = new ArrayList<ImageView>();
for (int i = 0; i < methods.size(); i++) {
String method = methods.get(i);
for (int j = 0; j < image_urls.size(); j++) {
String img_url = image_urls.get(j);
if (img_url.toLowerCase().contains(method.toLowerCase()) == true) {
ImageView image = new ImageView(mContext);
dateTV = viewHolder.dateTextView;
imageButton = viewHolder.thumbnail;
image.setId(generateViewId());
IMGS.add(image);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
if (IMGS.size() > 1) {
params.addRule(RelativeLayout.RIGHT_OF, IMGS.get(IMGS.size() - 1).getId());
params.addRule(RelativeLayout.ALIGN_TOP, IMGS.get(IMGS.size() - 1).getId());
params.addRule(RelativeLayout.END_OF, IMGS.get(IMGS.size() - 1).getId());
} else {
params.addRule(RelativeLayout.RIGHT_OF, imageButton.getId());
params.addRule(RelativeLayout.BELOW, dateTV.getId());
params.addRule(RelativeLayout.END_OF, imageButton.getId());
}
params.height = 65;
params.width = 65;
image.setLayoutParams(params);
viewHolder.relativeLayout.addView(image);
//viewHolder.relativeLayout.addView(rallyLayout);
Picasso.with(mContext).load(img_url).fit().centerCrop().into(image);
}
}
}
}
以下是视图在加载时的样子。
滚动了一下后...
我认为您需要 LinearLayout
在 for 循环之前按住图标并清除它:
viewHolder.linearLayout.removeAllViews();
因为我刚刚遇到了类似的问题,如果您在 onBindViewHolder() 中设置了很多样式,那么覆盖 onViewRecycled() 以及将视图恢复到其原始状态可能会有所帮助...