Представление поиска реализовано в панели действий, поиск работает нормально, но, например, Если пользователь ищет два символа pa, мой список содержит 2 данных, связанных с pa, то есть pack1, pack2, а затем данные загружаются в представление ресайклера. теперь, если пользователь вводит другой символ l вместо предыдущих символов pa, теперь в моем представлении поиска есть pal , но список массивов не совпадает с поиском, список не содержит ни одного элемента с pal. т. е. теперь представление ресайклера пусто. теперь, если я очищаю символ l, список перезагружается с пакетом данных1, пакетом2, но результат загружается 2 раза, то есть вместо отображения 2 элементов в recyclerview он показывает всего 4 элемента. Это дублирование элементов, когда поиск очищается.
SearchView
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_order, menu);
searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setMaxWidth(Integer.MAX_VALUE);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
mOrderAdapter.getFilter().filter(query);
searchView.clearFocus();
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
if (newText.length()==0){
getData();
searchView.clearFocus();
}
mOrderAdapter.getFilter().filter(newText);
return true ;
}
});
return true;
}
Код фильтра
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
String charString = constraint.toString();
if (charString.isEmpty()||charString.length()==0) {
mListFilter = mOrderArrayList;
} else {
List<Order> filteredList = new ArrayList<>();
ArrayList<Order> templist=new ArrayList<Order>();
for (Order ord : mOrderArrayList) {
if (ord.getOs_OrderNo().toLowerCase().contains(charString.toLowerCase())
|| ord.getItemName().toLowerCase().contains(charString.toLowerCase())) {
filteredList.add(ord);
templist.addAll(mListFilter);
}
}
mOrderArrayList.removeAll(templist);
mOrderArrayList.addAll(filteredList);
mListFilter = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = mListFilter;
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
mListFilter = (ArrayList<Order>) results.values;
notifyDataSetChanged();
}
};
}
Любая помощь очень ценится.
Код адаптера
public class OrderAdapter extends RecyclerView.Adapter<OrderAdapter.MyViewHolder> implements Filterable {
private Context mContext;
private List<Order> mListFilter,mOrderArrayList;
private SharedPreferences sharedPreferences;
private Resources r;
public OrderAdapter(Context context, ArrayList<Order> orderList) {
mContext = context;
mListFilter = orderList;
mOrderArrayList = orderList;
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
r = context.getResources();
}
class MyViewHolder extends RecyclerView.ViewHolder {
private TextView orderNoView, itemNameView, qtyView, statusView, companyNameView;
private Order currentItem;
MyViewHolder(View view) {
super(view);
orderNoView = view.findViewById(R.id.orderNo);
itemNameView = view.findViewById(R.id.item);
qtyView = view.findViewById(R.id.qty);
statusView = view.findViewById(R.id.status);
companyNameView = view.findViewById(R.id.company);
}
void bind (Order om) { //<--bind method allows the ViewHolder to bind to the data it is displaying
orderNoView.setText(om.getOs_OrderNo());
itemNameView.setText(String.valueOf(om.getItemName()));
qtyView.setText("Qty - " + String.valueOf(om.getOs_Qty()));
statusView.setText(om.getStatusName());
if (sharedPreferences.getString(r.getString(R.string.key_CompanyInUser), "").equals("0")){
companyNameView.setVisibility(View.GONE);
} else {
companyNameView.setText(om.getCustomerName());
}
currentItem = om; //<-- keep a reference to the current item
}
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.adapter_order, parent, false);
return new MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
Order item = mListFilter.get(position);
holder.bind(item);
}
@Override
public int getItemCount() {
return mListFilter.size();
}
@Override
public int getItemViewType(int position){
return position;
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
String charString = constraint.toString();
List<Order> filteredList = new ArrayList<>();
if (charString.isEmpty()||charString.length()==0) {
filteredList.addAll(mOrderArrayList);
} else {
for (Order ord : mOrderArrayList) {
if (ord.getOs_OrderNo().toLowerCase().contains(charString.toLowerCase())
|| ord.getItemName().toLowerCase().contains(charString.toLowerCase())) {
filteredList.add(ord);
}
}
}
FilterResults filterResults = new FilterResults();
filterResults.values = filteredList;
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
mListFilter = (ArrayList<Order>) results.values;
notifyDataSetChanged();
}
};
}
}
Код прослушивателя кликов
brandView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), brandView,
new RecyclerTouchListener.ClickListener() {
@Override
public void onClick(View view, int position) {
isRefreshData = true;
startActivity(new Intent(mContext, ViewOrderDetails.class).putExtra("Key-Intent-OrderNo",mOrderArrayList.get(position).getOs_OrderNo()).putExtra("Key-Intent-BrandName",mOrderArrayList.get(position).getos_BrandName()));
}
@Override
public void onLongClick(View view, int position) {
}
}));
Это потому, что вы используете addAll
внутри цикла в #performFiltering
. Также почему у вас есть два локальных списка для фильтрации? Проверьте метод ниже, он должен работать. я удалил лишний код и код, который вызывает проблему.
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
String charString = constraint.toString();
List<Order> filteredList = new ArrayList<>();
if (charString.isEmpty()||charString.length()==0) {
filteredList.addAll(mOrderArrayList);
} else {
for (Order ord : mOrderArrayList) {
if (ord.getOs_OrderNo().toLowerCase().contains(charString.toLowerCase())
|| ord.getItemName().toLowerCase().contains(charString.toLowerCase())) {
filteredList.add(ord);
}
}
}
FilterResults filterResults = new FilterResults();
filterResults.values = filteredList;
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
mListFilter = (ArrayList<Order>) results.values;
notifyDataSetChanged();
}
};
}
я добавил сэр
Код мне кажется нормальным. Попробуйте отладить
Спасибо. временный список был добавлен в код, потому что после фильтрации при нажатии на отфильтрованный элемент открывается другой элемент, т.е. он открывает элемент из основного списка, а не из отфильтрованного списка. Короче говоря, после фильтрации он занимает позицию основного списка, а не отфильтрованного списка. как я могу решить это с помощью кода сейчас
Я не вижу прослушиватель кликов в вашем коде. как вы добавляете прослушиватель кликов, обновляете рассматриваемый код. Вы должны использовать mListFilter, чтобы получить щелкнутый элемент
Я вызываю новую активность на touchlistener в добавленном коде представления recycler. этот код находится в действии. я добавил код
Установите прослушиватель на просмотр внутри адаптера, не используйте на сенсорном прослушивателе. stackoverflow.com/questions/24471109/recyclerview-onclick
Спасибо за помощь. решение работает. но появилась еще одна проблема. теперь, если я ввожу другой символ, такой как pac, после очистки этого дублирования происходит снова. два locallist были созданы, когда я столкнулся с аналогичной проблемой дублирования