滚动向下和向上滚动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;
}
}
答案 0 :(得分:36)
我遇到了同样的问题,我找到的唯一解决方案是:
holder.setIsRecyclable(false);
您的回收商将不再回收,因此当您滚动时项目将是相同的,如果您想要删除某些项目,请不要使用notifyitemRemoved(position)
,而是使用notifyDataSetChanged()
。
答案 1 :(得分:12)
在适配器构造函数中添加setHasStableIds(true);
在适配器中覆盖这两个方法。
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
return position;
}
答案 2 :(得分:2)
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);
}
答案 3 :(得分:1)
onBindHolder多次调用,因为Recycler View需要一个视图,除非是新视图。因此,每次在子视图中设置相关性时,其他视图状态也会发生变化。
无论何时向上和向下滚动,都会使用错误的可见性选项重新绘制这些视图,因此请始终指定这两个条件,因为回收者视图不会知道我们小部件的先前状态/条件/值。
解决方案:
如果在If块中你设置任何android widget.setVisibility(View.Gone)的可见性,那么在else块中你必须设置它的可见性相反的值,如widget.setVisibility(View.Visible)来克服上述问题
@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
viewHolder.tvName.setText(ModelCategoryProducts.name.get(i));
viewHolder.tvPrice.setText("Rs."+String.format("%.2f", Float.parseFloat(ModelCategoryProducts.price.get(i))));
if(ModelCategoryProducts.special_price.get(i).equals("null")) {
viewHolder.tvSpecialPrice.setVisibility(View.GONE); // here visibility is gone and in else it's opposite visibility i set.
viewHolder.tvPrice.setTextColor(Color.parseColor("#ff0000"));
viewHolder.tvPrice.setPaintFlags(0);// here paint flag is 0 and in else it's opposite flag that i want is set.
}else if(!ModelCategoryProducts.special_price.get(i).equals("null")){
viewHolder.tvPrice.setTextColor(Color.parseColor("#E0E0E0"));
viewHolder.tvSpecialPrice.setVisibility(View.VISIBLE);
viewHolder.tvSpecialPrice.setText("Rs." + String.format("%.2f", Float.parseFloat(ModelCategoryProducts.special_price.get(i))));
viewHolder.tvPrice.setPaintFlags(viewHolder.tvPrice.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
}
if (!ModelCategoryProducts.image_url.get(i).isEmpty()) {
Picasso.with(context)
.load(ModelCategoryProducts.image_url.get(i))
.into(viewHolder.ivProduct);
}
viewHolder.setClickListener(new ItemClickListener() {
@Override
public void onClick(View view, int position, boolean isLongClick) {
if (isLongClick) {
// Toast.makeText(context, "#" + position + " - " + ModelCategoryProducts.name.get(position) + " (Long click)", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "#" + position + " - " + ModelCategoryProducts.name.get(position), Toast.LENGTH_SHORT).show();
Intent i = new Intent(context, ProductDetail.class);
i.putExtra("position",position);
i.putExtra("flagHlvCheck", 5);
context.startActivity(i);
}
}
});
}
答案 4 :(得分:0)
@Override
public DataObjectHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.custom_layout, parent, false);
DataObjectHolder dataObjectHolder = new DataObjectHolder(view);
dataObjectHolder.setIsRecyclable(false);
return dataObjectHolder;
}
答案 5 :(得分:0)
最好的方法是将ArrayList指示为模型,并具有一些参数并为此定义setter和getter。
package com.test.mohammaddvi.snappfood.Model;
public class OfferList {
private boolean visibilityOrder;
private int number;
public OfferList(int number, boolean visibilityOrder) {
this.number=number;
this.visibilityOrder=visibilityOrder;
}
public boolean isVisibilityOrder() {
return visibilityOrder;
}
public void setVisibilityOrder(boolean visibilityOrder) {
this.visibilityOrder = visibilityOrder;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
并将变量设置为所需位置,并且必须在recyclerview Adapter的onBindViewHolder中进行设置:
if (offerList.isVisibilityOrder()) {
holder.foodMinusButton.setVisibility(View.VISIBLE);
holder.foodOrderNumber.setText(offerList.getNumber() + "");
holder.foodOrderNumber.setVisibility(View.VISIBLE);
} else {
holder.foodMinusButton.setVisibility(View.INVISIBLE);
}
并将其指示为您的recyclerview适配器:
public class RecyclerViewMenuFragmentAdapter extends RecyclerView.Adapter<RecyclerViewMenuFragmentAdapter.SingleItemInMenuFragment> {
private ArrayList<Food> foodList;
private Context mContext;
private List<OfferList> offers;
public RecyclerViewMenuFragmentAdapter(ArrayList<Food> foodList, Context mContext, List<OfferList> offers) {
this.foodList = foodList;
this.mContext = mContext;
this.offers = offers;
}
答案 6 :(得分:0)
尝试将其添加到适配器中。
@Override
public int getItemViewType(int position)
{
return position;
}
答案 7 :(得分:0)
@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
final UserData userdata = userdataList.get(position);
holder.setIsRecyclable(false);
holder.name.setText(userdata.getName());
holder.active.setChecked(userdata.getActive());
String userPic = userdata.getPic();
holder.active.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked){
userdata.setActive(isChecked);
}
});
}
答案 8 :(得分:0)
class AnyRVAdapter: androidx.recyclerview.widget.RecyclerView.Adapter<AnyRVAdapter.MViewHolder>() {
// put saver outside viewholder
val saveLayId = mutableListOf<Int>()
inner class MViewHolder(itemView: View) :
androidx.recyclerview.widget.RecyclerView.ViewHolder(itemView) {
fun bindModel(d: TesListModel.MList, position:Int) {
// concept here
val showedId= saveLayId.find { s -> s == layoutPosition}
if (idClicked == null) {
// save the layout id
lyClicked.visibility = View.VISIBLE
saveLayId.add(layoutPosition)
} else {
// remove the layout id
lyClicked.visibility = View.INVISIBLE
saveLayId.remove(layoutPosition)
}
}
}
但是我认为这段代码很沉重,因为您将其用于大型数据列表。
答案 9 :(得分:0)
如果有人可能会遇到视点持有人中某些字段获取随机值的问题,请尝试将所有字段设置为至少具有默认值。