Как удалить при смахивании элемент из списка отфильтрованных?[RecyclerView] - PullRequest
0 голосов
/ 12 сентября 2018

У меня возникла проблема при попытке удалить элемент из RecyclerView после того, как я искал его с помощью SearchView, а если я не использую SearchView и не удаляю элемент как обычно, он работает нормально.

Вот пример, где я удаляю элемент, и где я ищу 2, удаляя его, и он все еще остается в списке.

enter image description here

В то время как здесь есть метод, где я удаляю элемент при смахивании в моей деятельности

  new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
        @Override
        public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
            return false;
        }

        @Override
        public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {

            if (direction == ItemTouchHelper.RIGHT) {
                itemAdapter.removeItem( viewHolder.getAdapterPosition());
            }

            if (direction == ItemTouchHelper.LEFT) {
                itemAdapter.removeItem( viewHolder.getAdapterPosition());
            }

        }
    }).attachToRecyclerView(recyclerView);

}

Пока здесь код от моего адаптера

public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ExampleViewHolder>  implements Filterable {


    private ArrayList<ItemModel> variantiConstructors;
    private ArrayList<ItemModel> mFilteredList;
    private OnItemClickListener mListener;

    public interface  OnItemClickListener{
        void onItemClick(int position);
    }

    public void setOnItemClickListener(OnItemClickListener listener){
        mListener = listener;
    }

    @NonNull
    @Override
    public ItemAdapter.ExampleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycler,parent,false);
        RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        v.setLayoutParams(lp);
        return new ItemAdapter.ExampleViewHolder(v, mListener);
    }

    ItemAdapter(ArrayList<ItemModel> exampleList){
        variantiConstructors = exampleList;
        mFilteredList = variantiConstructors;
    }

    @Override
    public void onBindViewHolder(@NonNull final ItemAdapter.ExampleViewHolder holder, @SuppressLint("RecyclerView") final int position) {
        ItemModel item = variantiConstructors.get(position);

        holder.desc.setText(item.getCodiceArticolo());
        holder.qta.setText(item.getQta());

        holder.qta.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                variantiConstructors.get(position).setQta(holder.qta.getText().toString());
            }

            @Override
            public void afterTextChanged(Editable editable) {
            }
        });


        if(position % 2 == 0 ){
            holder.itemView.setBackgroundColor(Color.parseColor("#5C5C5C"));

        }else if(position % 2 == 1){
            holder.itemView.setBackgroundColor(Color.parseColor("#9E9E9E"));
        }
    }


    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                final FilterResults oReturn = new FilterResults();
                final ArrayList<ItemModel> results = new ArrayList<>();
                if (mFilteredList == null)
                    mFilteredList = new ArrayList<>(variantiConstructors);
                if (constraint != null && constraint.length() > 0) {
                    if (mFilteredList != null && mFilteredList.size() > 0) {
                        for (final ItemModel cd : mFilteredList) {
                            if (cd.getCodiceArticolo().toLowerCase()
                                    .contains(constraint.toString().toLowerCase()))
                                results.add(cd);
                        }
                    }
                    oReturn.values = results;
                    oReturn.count = results.size(); //newly Aded by ZA
                } else {
                    oReturn.values = mFilteredList;
                    oReturn.count = mFilteredList.size(); //newly added by ZA
                }
                return oReturn;
            }

            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(final CharSequence constraint,
                                          FilterResults results) {
                variantiConstructors = new ArrayList<>((ArrayList<ItemModel>) results.values);
                notifyDataSetChanged();
            }
        };
    }

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

    public class ExampleViewHolder extends RecyclerView.ViewHolder {

        public TextView desc;
        public EditText qta;

        ExampleViewHolder(View itemView, final OnItemClickListener listener) {
            super(itemView);

            desc = itemView.findViewById(R.id.Desc);
            qta = itemView.findViewById(R.id.Qta);


            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(listener != null){
                        int position = getAdapterPosition();
                        if(position != RecyclerView.NO_POSITION){
                            listener.onItemClick(position);
                        }
                    }
                }
            });


        }
    }

    public ArrayList<ItemModel> getList(){
        return variantiConstructors;
    }

    public void removeItem(int position) {
        variantiConstructors.remove(position);
        notifyDataSetChanged();
    }
}

Ответы [ 4 ]

0 голосов
/ 06 декабря 2018

Я давно сталкивался с этой проблемой.Но, наконец, я нашел работу вокруг.Вот класс адаптера:

public class DataAdapter extends RecyclerView.Adapter<DataAdapter.DataHolder> implements Filterable {

private List<DataModel> dataList;
private List<DataModel> dataListUnFilter;

private RecyclerListener mRecyclerListener;
private SearchFilter mSearchFilter;

private String mSearchTerm;

DataAdapter(List<DataModel> dataList) {
    this.dataList = dataList;
    this.dataListUnFilter = new ArrayList<>();
}

void setRecyclerListener(@NonNull RecyclerListener mRecyclerListener) {
    this.mRecyclerListener = mRecyclerListener;
}

@NonNull
@Override
public DataHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
    View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.data_model, viewGroup, false);
    return new DataHolder(v);
}

@Override
public void onBindViewHolder(@NonNull DataHolder dataHolder, int i) {
    DataModel data = dataList.get(i);

    dataHolder.tvSubtitle.setText(data.getSubtitle());

    String title = data.getTitle();

    if (TextUtils.isEmpty(mSearchTerm)) {
        dataHolder.tvTitle.setText(title);
    } else {
        int startPos = title.toLowerCase().indexOf(mSearchTerm.toLowerCase());
        int endPos = startPos + mSearchTerm.length();

        if (startPos != -1) {
            Spannable spannable = new SpannableString(title);
            ColorStateList blueColor = new ColorStateList(new int[][]{new int[]{}}, new int[]{Color.BLUE});
            TextAppearanceSpan highlightText = new TextAppearanceSpan(null, Typeface.NORMAL, -1, blueColor, null);
            spannable.setSpan(highlightText, startPos, endPos, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            dataHolder.tvTitle.setText(spannable);
        } else {
            dataHolder.tvTitle.setText(title);
        }
    }
}

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

// Filterable method
@Override
public Filter getFilter() {

    if (mSearchFilter == null) {
        dataListUnFilter.clear();
        dataListUnFilter.addAll(this.dataList);
        mSearchFilter = new SearchFilter(dataListUnFilter);
    }
    return mSearchFilter;
}


/**
 * Custom Filter class to overtake List Items issue
 * Delete Items while searching that are revised on refresh search
 */
class SearchFilter extends Filter {

    private List<DataModel> listToFilter;

    SearchFilter(List<DataModel> listToFilter) {
        this.listToFilter = listToFilter;
    }

    // Update Base Search List on Item Removed while searching
    void updateList(DataModel dataModel) {
        listToFilter.remove(dataModel);
    }

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        String searchString = constraint.toString().toLowerCase().trim();
        mSearchTerm = searchString;

        FilterResults results = new FilterResults();

        if (TextUtils.isEmpty(searchString)) {
            results.values = listToFilter;
        } else {
            List<DataModel> filteredList = new ArrayList<>();

            for (DataModel dm : listToFilter) {
                if (dm.getTitle().toLowerCase().contains(searchString)) {
                    filteredList.add(dm);
                }
            }
            results.values = filteredList;
        }
        return results;
    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        //noinspection unchecked
        dataList = (List<DataModel>) results.values;
        notifyDataSetChanged();
    }
}

/**
 * ViewHolder class of DataModel
 */
class DataHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    private TextView tvTitle, tvSubtitle;
    private ImageButton btnDelete;

    DataHolder(@NonNull View itemView) {
        super(itemView);
        tvTitle = itemView.findViewById(R.id.tvTitle);
        tvSubtitle = itemView.findViewById(R.id.tvSubTitle);
        btnDelete = itemView.findViewById(R.id.btnDelete);

        btnDelete.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {

        final int pos = getAdapterPosition();
        DataModel dataModel = dataList.get(pos);

        mRecyclerListener.onItemClick(v, pos, dataModel);

        // Remove item from Adapter List and notify
        dataList.remove(pos);
        notifyItemRemoved(pos);

        // Remove Object from Original Data from SearchFilter Class
        if (mSearchFilter != null) {
            mSearchFilter.updateList(dataModel);
        }
    }
}


public interface RecyclerListener {
    void onItemClick(View view, int position, DataModel dataModel);
}

}

Полный источник: https://github.com/DekDhamecha/DynamicListSearch

Когда элемент удаляется во время поиска, оба ArrayLists т.е. ArrayList of Filter иArrayList адаптера должен быть обновлен.

0 голосов
/ 25 сентября 2018

Поскольку вы удаляете данные из списка, который вы заполнили с помощью recylerView, и вы не удаляете данные из отфильтрованного списка, поэтому он показывает ..

public void removeItem(int position) {
        variantiConstructors.remove(position);
        mFilteredList .remove(position);
        notifyDataSetChanged();
    }
0 голосов
/ 25 сентября 2018

Попробуйте, я сделал некоторые изменения в вашем коде

MainActivity код

public class MainActivity extends AppCompatActivity {

    ItemModel itemModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        findViewById(R.id.btnShow).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showCustomDialog();
            }
        });

    }

    private void showCustomDialog() {

        final Dialog dialog = new Dialog(this);
        final ArrayList<ItemModel> arrayList = new ArrayList<>();


        dialog.setContentView(R.layout.custom_dialog);

        RecyclerView myRecyclerView = dialog.findViewById(R.id.myRecyclerView);

        ImageView ivDelete = dialog.findViewById(R.id.ivDelete);
        ImageView ivClose = dialog.findViewById(R.id.ivClose);

        final EditText edtSearch = dialog.findViewById(R.id.edtSearch);

        arrayList.add(new ItemModel("Nilesh", String.valueOf(1)));
        arrayList.add(new ItemModel("NEEL", String.valueOf(1)));
        arrayList.add(new ItemModel("Prem", String.valueOf(1)));
        arrayList.add(new ItemModel("Rathod", String.valueOf(1)));
        arrayList.add(new ItemModel("Android", String.valueOf(1)));
        arrayList.add(new ItemModel("Kanudo", String.valueOf(1)));


        myRecyclerView.setHasFixedSize(true);
        myRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        ivClose.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });

        final ItemAdapter itemAdapter = new ItemAdapter(arrayList);
        myRecyclerView.setAdapter(itemAdapter);

        new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
            @Override
            public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
                return false;
            }

            @Override
            public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {

                if (direction == ItemTouchHelper.RIGHT || direction == ItemTouchHelper.LEFT) {
                    itemModel = itemAdapter.getModel();
                    itemAdapter.removeItem(viewHolder.getAdapterPosition());


                }

            }
        }).attachToRecyclerView(myRecyclerView);

        edtSearch.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

                if (edtSearch.getText().toString().isEmpty()) {
                    if (itemModel != null)
                        arrayList.remove(itemModel);
                }
                itemAdapter.getFilter().filter(edtSearch.getText().toString().toLowerCase());



            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

        dialog.show();

    }

}

Код ItemAdapter

public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ExampleViewHolder> implements Filterable {


    private ArrayList<ItemModel> variantiConstructors;
    private ArrayList<ItemModel> mFilteredList;
    private OnItemClickListener mListener;
    ItemModel itemModel;

    ItemAdapter(ArrayList<ItemModel> exampleList) {
        variantiConstructors = exampleList;
        mFilteredList = variantiConstructors;
    }


    public interface OnItemClickListener {
        void onItemClick(int position);
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        mListener = listener;
    }

    @NonNull
    @Override
    public ItemAdapter.ExampleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_item_layout, parent, false);
        RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        v.setLayoutParams(lp);
        return new ItemAdapter.ExampleViewHolder(v, mListener);
    }


    @Override
    public void onBindViewHolder(@NonNull final ExampleViewHolder holder, @SuppressLint("RecyclerView") final int position) {
        ItemModel item = variantiConstructors.get(position);

        holder.desc.setText(item.getItemName());
        holder.qta.setText(item.getQty());

        itemModel = item;

        if (position % 2 == 0) {
            holder.itemView.setBackgroundColor(Color.parseColor("#5C5C5C"));

        } else if (position % 2 == 1) {
            holder.itemView.setBackgroundColor(Color.parseColor("#9E9E9E"));
        }
    }


    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                final FilterResults oReturn = new FilterResults();
                final ArrayList<ItemModel> results = new ArrayList<>();
                if (mFilteredList == null)
                    mFilteredList = new ArrayList<>(variantiConstructors);
                if (constraint != null && constraint.length() > 0) {
                    if (mFilteredList != null && mFilteredList.size() > 0) {
                        for (final ItemModel cd : mFilteredList) {
                            if (cd.getItemName().toLowerCase()
                                    .contains(constraint.toString().toLowerCase()))
                                results.add(cd);
                        }
                    }
                    oReturn.values = results;
                    oReturn.count = results.size(); //newly Aded by ZA
                } else {
                    oReturn.values = mFilteredList;
                    oReturn.count = mFilteredList.size(); //newly added by ZA
                }
                return oReturn;
            }

            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(final CharSequence constraint,
                                          FilterResults results) {
                variantiConstructors = new ArrayList<>((ArrayList<ItemModel>) results.values);
                notifyDataSetChanged();
            }
        };
    }

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

    public class ExampleViewHolder extends RecyclerView.ViewHolder {

        public TextView desc;
        public TextView qta;

        ExampleViewHolder(View itemView, final OnItemClickListener listener) {
            super(itemView);

            desc = itemView.findViewById(R.id.itemName);
            qta = itemView.findViewById(R.id.Qta);


            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (listener != null) {
                        int position = getAdapterPosition();
                        if (position != RecyclerView.NO_POSITION) {
                            listener.onItemClick(position);
                        }
                    }
                }
            });


        }
    }

    public ItemModel getModel() {
        return itemModel;

    }

    public ArrayList<ItemModel> getList() {
        return variantiConstructors;
    }

    public void removeItem(int position) {
        variantiConstructors.remove(position);
        notifyDataSetChanged();
    }
}

OUTPUT

https://www.youtube.com/watch?v=T80bk0756xk

0 голосов
/ 20 сентября 2018

Проверьте код в методе getFilter().Вы можете ясно видеть, что фильтр хранит список элементов внутри временного списка, потому что во время фильтрации основной список отключается.Поэтому, когда вы удаляете / удаляете элемент из отфильтрованного списка, вы удаляете его из временного списка, а не из основного списка.

Хотя возможны обходные пути с использованием getFilter() и SearchView, я бы порекомендовал использоватьнастраиваемый вид поиска, который делает вашу задачу намного проще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...