RecyclerView在滚动时弄乱了数据

k.n*_*nko 11 java android android-recyclerview

滚动向下和向上滚动RecyclerView时遇到问题.这个想法是改变元素的颜色,但是当我向下滚动时,一切都很棒,当滚动向上时 - 不应该着色的元素会改变颜色.

这是我的适配器:

public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdapter.ViewHolder> {

private NotificationData notificationData;
private Context mContext;
private ArrayList<NotificationData> infromationList = new ArrayList<>();


public NotificationsAdapter(Context context, ArrayList<NotificationData> infromationList) {
    this.infromationList = infromationList;
    this.mContext = context;
}


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

    View itemLayoutView;
    ViewHolder viewHolder;

    itemLayoutView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.notification_single_item, parent, false);
    viewHolder = new ViewHolder(itemLayoutView, viewType);

    return viewHolder;
}

@Override
public void onBindViewHolder(NotificationsAdapter.ViewHolder holder, int position) {

    notificationData = infromationList.get(position);
    holder.notificationDate.setText(convertDate(notificationData.getDate()));
    holder.notificationStatus.setText(notificationData.getNotificationStatus());
    holder.orderDescription.setText(notificationData.getNotificationLabel());

    if ("true".equals(notificationData.getReadStatus())) {
        holder.root.setBackgroundColor(mContext.getResources().getColor(R.color.white));
        holder.notificationStatus.setTypeface(Typeface.create("sans-serif-light", Typeface.NORMAL));
    }

}

@Override
public int getItemCount() {
    return (null != infromationList ? infromationList.size() : 0);
}

public static class ViewHolder extends RecyclerView.ViewHolder {

    public TextView notificationDate;
    public TextView notificationStatus;
    public TextView orderDescription;
    public LinearLayout root;

    public ViewHolder(View itemView, int position) {
        super(itemView);

        notificationDate = (TextView) itemView.findViewById(R.id.notificationDate);
        notificationStatus = (TextView) itemView.findViewById(R.id.notificationStatus);
        orderDescription = (TextView) itemView.findViewById(R.id.orderDescription);
        root = (LinearLayout) itemView.findViewById(R.id.root);
    }

}

private String convertDate(String date) {
    String convertedDate;

    String[] parts = new String[2];
    parts = date.split("T");
    date = parts[0];

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd");
    Date testDate = null;
    try {
        testDate = sdf.parse(date);
    }catch(Exception ex){
        ex.printStackTrace();
    }
    SimpleDateFormat formatter = new SimpleDateFormat("dd.mm.yyyy");
    convertedDate = formatter.format(testDate);

    return convertedDate;
}
}
Run Code Online (Sandbox Code Playgroud)

小智 37

我有同样的问题,我找到的唯一解决方案是:

holder.setIsRecyclable(false);
Run Code Online (Sandbox Code Playgroud)

您的回收商将不再回收,因此当您滚动时项目将是相同的,如果您想要删除某些项目不使用notifyitemRemoved(position),请notifyDataSetChanged()改用.

  • 请注意:您不应该使用这些建议中的任何一个.正如Jhonatan所说,这些观点将不再被回收,完全丧失了回收利用的目的,并将导致糟糕的表现.另外,使用强力通知notifyDataSetChanged()应始终是最后的手段 - 如果可能的话,尝试让适配器确切地知道在删除或添加数据时哪些项目已更新 - 这不仅可以提高性能,还可以让它适当地执行动画. (7认同)

小智 14

添加setHasStableIds(true);适配器构造函数并在适配器中覆盖这两个方法.

@Override
public long getItemId(int position) {
            return position;
}

@Override
public int getItemViewType(int position) {
       return position;
}
Run Code Online (Sandbox Code Playgroud)

  • 这对我有用.你能提供更多解释为何有效吗? (2认同)

Xci*_*egn 5

你的有问题onBindViewHolder(...),应该是:

if ("true".equals(notificationData.getReadStatus())) {
    holder.root.setBackgroundColor(mContext.getResources().getColor(R.color.white));
    holder.notificationStatus.setTypeface(Typeface.create("sans-serif-light", Typeface.NORMAL));
}
else {
    holder.root.setBackgroundColor(yourDefaultColor);
    holder.notificationStatus.setTypeface(yourDefaultTypeface);

}
Run Code Online (Sandbox Code Playgroud)