上下滚动后滚动 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;
}
}
我有同样的问题,我找到的唯一解决方案是:
holder.setIsRecyclable(false);
您的回收商将不再回收,因此滚动时项目将相同,如果您想删除某些项目,请不要使用
notifyitemRemoved(position)
,请改用notifyDataSetChanged()
。
在您的适配器构造函数中添加
setHasStableIds(true);
和
在适配器中覆盖这两个方法。
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
return position;
}
你的
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);
}
@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);
}
});
}
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);
}
}
});
}
尝试在适配器中添加它。
@Override
public int getItemViewType(int position)
{
return position;
}
如果有人可能会遇到取景器中的某些字段获取随机值的问题,请尝试使用至少任何默认值设置所有字段。
@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;
}
最好的方法是将 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 适配器的 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;
}
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)
}
}
}
但我认为如果您用于大型数据集,这段代码会很重。
伙计们,这对我有用..
override fun setHasStableIds(hasStableIds: Boolean) {
setHasStableIds(true)
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getItemViewType(position: Int): Int {
return position
}
在您的 onBindView 方法中,请将此设置为 false
holder.setIsRecyclable(假)