Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/189.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 在筛选recyclerview时,项目被复制_Android_Mvvm_Android Recyclerview_Filtering_Android Livedata - Fatal编程技术网

Android 在筛选recyclerview时,项目被复制

Android 在筛选recyclerview时,项目被复制,android,mvvm,android-recyclerview,filtering,android-livedata,Android,Mvvm,Android Recyclerview,Filtering,Android Livedata,我有一个RecyclerView,它显示了使用MVVM从房间db获取的数据。此外,我还有一个用于搜索或筛选recyclerview项目的ediitext。问题是当我按下recyclerview项(更新数据库中的一些值)然后过滤它时,它会过滤但会复制所有数据。 代码如下: 完整的适配器代码: private Context mCtx; private List<AttendeesTable> itemList = new ArrayList<>(); private Lis

我有一个RecyclerView,它显示了使用MVVM从房间db获取的数据。此外,我还有一个用于搜索或筛选recyclerview项目的ediitext。问题是当我按下recyclerview项(更新数据库中的一些值)然后过滤它时,它会过滤但会复制所有数据。 代码如下: 完整的适配器代码:

private Context mCtx;
private List<AttendeesTable> itemList = new ArrayList<>();
private List<AttendeesTable> filterItemList = new ArrayList<>();
private EventsViewModel eventsViewModel;
long DURATION = 500;
private boolean on_attach = true;
public AttendeesAdapter() {
}
@NonNull
@Override
public EventsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_attendance, parent, false);
    return new EventsViewHolder(view, mCtx, viewType);
}
@Override
public void onBindViewHolder(@NonNull final EventsViewHolder holder, final int position) {
    final int is_arrived = itemList.get(position).getHas_arrived();
    if (is_arrived == 1){
        holder.attendee_arrived_not.setVisibility(View.INVISIBLE);
        holder.attendee_arrived.setVisibility(View.VISIBLE);
        holder.attendee_view.setCardBackgroundColor(Color.parseColor("#dcffda"));
    }else if (is_arrived ==0){
        holder.attendee_arrived_not.setVisibility(View.VISIBLE);
        holder.attendee_arrived.setVisibility(View.INVISIBLE);
        holder.attendee_view.setCardBackgroundColor(Color.WHITE);
    }
    setAnimation(holder.itemView,position);
    holder.attendeeSeatNumber.setText(itemList.get(position).getSeat_no());
    holder.attendeeTicketNo.setText(itemList.get(position).getTicket_no());
    holder.mView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
            String currentDateandTime = sdf.format(new Date());
            if (is_arrived == 0){
                eventsViewModel.updateAttendees(1,currentDateandTime, itemList.get(position).getQr_code_id());
                holder.attendee_arrived_not.setVisibility(View.INVISIBLE);
                holder.attendee_arrived.setVisibility(View.VISIBLE);
                notifyItemRemoved(position);
                holder.attendee_view.setCardBackgroundColor(Color.parseColor("#dcffda"))z
            }else if (is_arrived ==1){
                eventsViewModel.updateAttendees(0,"no_time", itemList.get(position).getQr_code_id());
                holder.attendee_arrived_not.setVisibility(View.VISIBLE);
                holder.attendee_arrived.setVisibility(View.INVISIBLE);
                holder.attendee_view.setCardBackgroundColor(Color.WHITE);
                notifyItemRemoved(position);
            }

        }
    });
}
@Override
public int getItemCount() {
    return itemList.size();
}

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

@Override
public int getItemViewType(int position) {
    return position;
}

@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            constraint = constraint.toString().toLowerCase().trim();
            itemList.clear();
            if (constraint.length() == 0) {
                itemList.addAll(filterItemList);
            } else {
                for (AttendeesTable item : filterItemList) {

                    String name =  item.getFirst_name() + " " + item.getLast_name();
                    if (item.getTicket_no().toLowerCase(Locale.getDefault()).contains(constraint) ||
                            item.getEmail().toLowerCase(Locale.getDefault()).contains(constraint) ||
                            name.toLowerCase(Locale.getDefault()).contains(constraint) ||
                            item.getSeat_no().toLowerCase(Locale.getDefault()).contains(constraint)){
                        itemList.add(item);
                    }
                }
            }
            FilterResults results = new FilterResults();
            results.values = itemList;
            return results;
        }
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            notifyDataSetChanged();
        }
    };
}
public class EventsViewHolder extends RecyclerView.ViewHolder {
    TextView attendeeName, attendeeEmail, attendeeSeatNumber, attendeeTicketNo;
    ImageView attendee_arrived, attendee_arrived_not;
    CardView attendee_view;
    public Context context;
    View mView;

    public EventsViewHolder(View itemView, Context context, int viewType) {
        super(itemView);
        mView = itemView;
        this.context = context;

        attendeeEmail = itemView.findViewById(R.id.attendee_email);
        attendeeName = itemView.findViewById(R.id.attendee_name);
        attendeeSeatNumber = itemView.findViewById(R.id.attendee_seat_number);
        attendee_arrived = itemView.findViewById(R.id.attendee_arrived);
        attendee_arrived_not = itemView.findViewById(R.id.attendee_arrived_x);
        attendee_view = itemView.findViewById(R.id.attendee_view);
        attendeeTicketNo = itemView.findViewById(R.id.attendee_ticket_no);
    }
}
public void setAttendees(List<AttendeesTable> events, Context mCtx, EventsViewModel eventsViewModel) {
    this.itemList = events;
    this.mCtx = mCtx;
    this.eventsViewModel = eventsViewModel;
    filterItemList.addAll(events);
    notifyDataSetChanged();
}
@Override
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
    recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
            Log.d(TAG, "onScrollStateChanged: Called " + newState);
            on_attach = false;
            super.onScrollStateChanged(recyclerView, newState);
        }
    });
    super.onAttachedToRecyclerView(recyclerView);
}
private void setAnimation(View itemView, int i) {
    if(!on_attach){
        i = -1;
    }
    boolean isNotFirstItem = i == -1;
    i++;
    itemView.setAlpha(0.f);
    AnimatorSet animatorSet = new AnimatorSet();
    ObjectAnimator animator = ObjectAnimator.ofFloat(itemView, "alpha", 0.f, 0.5f, 1.0f);
    ObjectAnimator.ofFloat(itemView, "alpha", 0.f).start();
    animator.setStartDelay(isNotFirstItem ? DURATION / 2 : (i * DURATION / 3));
    animator.setDuration(500);
    animatorSet.play(animator);
    animator.start();
}
以下是单击项目前的屏幕截图:

单击并过滤后:

对我来说,这是使用MVVM的更好方法

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

private List<AttendeesTable> items;

private List<AttendeesTable> filteredItems = new ArrayList<>();

private String filter = "";

//Call this method each time your data change
public void setItems(List<AttendeesTable> newItems){
    items = newItems;
    filteredItems.clear();
    filteredItems.addAll(items);
    calcDiff();
}

//Call this method for filter items with the string of your editText
//Don't forget to call trim() in the string before to call this method to avoid a malformed filter
public void filterItems(String externalFilter){
    this.filter = externalFilter;
    filteredItems.clear();
    for (AttendeesTable attendeesTable:
            items) {
        //Add all your constraints here
        if (attendeesTable.getId().contains(filter)){
            filteredItems.add(attendeesTable);
        }
        calcDiff();

    }
}

//This diffUtil calculates the changes automatically
private void calcDiff(){

    DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DiffUtil.Callback() {
        @Override
        public int getOldListSize() {
            return items.size();
        }

        @Override
        public int getNewListSize() {
            return filteredItems.size();
        }

        @Override
        public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
            //Just check the ID
            String oldIdAtPosition = items.get(oldItemPosition).getId();
            String newIdAtPosition = filteredItems.get(newItemPosition).getId();
            return oldIdAtPosition.equals(newIdAtPosition);
        }

        @Override
        public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
            // You can add more conditions here for check if the items are the same,
            // but in this case is enough to checking the ids of each item, unless
            // you have state changes like item selected or name of the item changed
            String oldIdAtPosition = items.get(oldItemPosition).getId();
            String newIdAtPosition = filteredItems.get(newItemPosition).getId();
            return oldIdAtPosition.equals(newIdAtPosition);
        }
    });

    diffResult.dispatchUpdatesTo(this);
}


@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    //Return your ViewHolder Here
}

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
    //Play with your viewHolder here
}

@Override
public int getItemCount() {
    //return your filteredItems size
    return filteredItems.size();
}
公共类differexampleAdapter扩展了RecyclerView.Adapter{ 私人清单项目; private List filteredItems=new ArrayList(); 私有字符串过滤器=”; //每次数据更改时调用此方法 公共无效集合项(列出新项){ 项目=新项目; filteredItems.clear(); filteredItems.addAll(项目); calcDiff(); } //为具有editText字符串的筛选器项调用此方法 //在调用此方法之前,不要忘记在字符串中调用trim(),以避免出现格式错误的筛选器 公共无效筛选器项(字符串外部筛选器){ this.filter=externalFilter; filteredItems.clear(); 对于(AttendeStable AttendeStable: (项目){ //在此处添加所有约束 if(attendestable.getId().contains(filter)){ filteredItems.add(attendestable); } calcDiff(); } } //此diffUtil自动计算更改 私有void calcDiff(){ DiffUtil.diffesult diffesult=DiffUtil.calculateDiff(新的DiffUtil.Callback(){ @凌驾 public int getOldListSize(){ 返回items.size(); } @凌驾 public int getNewListSize(){ 返回filteredItems.size(); } @凌驾 公共布尔值areItemsTheSame(int-oldItemPosition,int-newItemPosition){ //检查一下身份证就行了 字符串oldIdAtPosition=items.get(oldItemPosition.getId(); 字符串newIdAtPosition=filteredItems.get(newItemPosition.getId(); 返回oldIdAtPosition.equals(newIdAtPosition); } @凌驾 公共布尔值是相同的内容(int oldItemPosition,int newItemPosition){ //您可以在此处添加更多条件以检查项目是否相同, //但在这种情况下,检查每个项目的ID就足够了,除非 //您的状态发生了更改,如“已选择项目”或“已更改项目名称” 字符串oldIdAtPosition=items.get(oldItemPosition.getId(); 字符串newIdAtPosition=filteredItems.get(newItemPosition.getId(); 返回oldIdAtPosition.equals(newIdAtPosition); } }); diffResult.dispatchUpdatesTo(本); } @非空 @凌驾 public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup父级,int-viewType){ //在这里归还您的取景器 } @凌驾 public void onBindViewHolder(@NonNull RecyclerView.ViewHolder,int位置){ //在这里玩你的取景器 } @凌驾 public int getItemCount(){ //返回您的filteredItems大小 返回filteredItems.size(); } }


这样,您可以确保不会有重复的项。

您使用的是DiffUtil吗?添加完整的适配器code@Md.Asaduzzaman,添加了完整的适配器code@MijaelViricochea不,我不用它。我需要用它吗?如果是,为什么?@MijaelViricochea,我现在读到了。如果我是对的,它用于用新列表更新上一个列表。我尝试了这段代码,但不幸的是,筛选的项目没有更新shown@White是否在筛选之前调用setItems()方法?是的,它会获取所有数据,但当我开始筛选时,所有数据都会消失
public class DiffExampleAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

private List<AttendeesTable> items;

private List<AttendeesTable> filteredItems = new ArrayList<>();

private String filter = "";

//Call this method each time your data change
public void setItems(List<AttendeesTable> newItems){
    items = newItems;
    filteredItems.clear();
    filteredItems.addAll(items);
    calcDiff();
}

//Call this method for filter items with the string of your editText
//Don't forget to call trim() in the string before to call this method to avoid a malformed filter
public void filterItems(String externalFilter){
    this.filter = externalFilter;
    filteredItems.clear();
    for (AttendeesTable attendeesTable:
            items) {
        //Add all your constraints here
        if (attendeesTable.getId().contains(filter)){
            filteredItems.add(attendeesTable);
        }
        calcDiff();

    }
}

//This diffUtil calculates the changes automatically
private void calcDiff(){

    DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DiffUtil.Callback() {
        @Override
        public int getOldListSize() {
            return items.size();
        }

        @Override
        public int getNewListSize() {
            return filteredItems.size();
        }

        @Override
        public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
            //Just check the ID
            String oldIdAtPosition = items.get(oldItemPosition).getId();
            String newIdAtPosition = filteredItems.get(newItemPosition).getId();
            return oldIdAtPosition.equals(newIdAtPosition);
        }

        @Override
        public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
            // You can add more conditions here for check if the items are the same,
            // but in this case is enough to checking the ids of each item, unless
            // you have state changes like item selected or name of the item changed
            String oldIdAtPosition = items.get(oldItemPosition).getId();
            String newIdAtPosition = filteredItems.get(newItemPosition).getId();
            return oldIdAtPosition.equals(newIdAtPosition);
        }
    });

    diffResult.dispatchUpdatesTo(this);
}


@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    //Return your ViewHolder Here
}

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
    //Play with your viewHolder here
}

@Override
public int getItemCount() {
    //return your filteredItems size
    return filteredItems.size();
}