我在使用SearchView搜索后尝试从RecyclerView删除项目时遇到问题,而如果我不使用SearchView并正常删除项目,则可以正常工作。
这里是一个示例,其中我正在删除该项目,并且正在搜索2删除该项目,并且该项目仍保留在列表中。
这是我在“活动”中滑动时删除项目的方法
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();
}
}
答案 0 :(得分:1)
尝试一下,我对您的代码进行了一些更改
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();
}
}
输出
答案 1 :(得分:0)
检查3
方法中的代码。您可以清楚地看到过滤器将项目列表保留在临时列表内,因为在过滤过程中主列表被切换了。因此,当您从过滤列表中删除/删除项目时,您将从临时列表中删除,而不是从主列表中删除。
尽管使用getFilter()
和getFilter()
可能有一种解决方法,但我建议您使用自定义搜索视图,这会使您的任务更加简单。
答案 2 :(得分:0)
因为您要从使用recylerView填充的列表中删除数据,而没有从过滤的列表中删除其显示原因的数据。
public void removeItem(int position) {
variantiConstructors.remove(position);
mFilteredList .remove(position);
notifyDataSetChanged();
}
答案 3 :(得分:0)
我很早以前就遇到了这个问题。但最后我找到了解决方法。 这是适配器类:
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
在搜索过程中删除该项目时,必须同时更新两个ArrayList,即Filter的ArrayList和Adapter的ArrayList。