Я пытаюсь реализовать функцию поиска для приложения, которое заполняет посетителей из Firebase.У объекта 'meeting' есть список целых чисел, содержащий идентификаторы пользователей, и приложение переходит в базу данных Firebase и создает объекты 'user' для каждого пользователя, посещающего эту конкретную встречу.
Я пытаюсь включить функцию поиска, котораяпоможет отфильтровать и найти пользователей по их имени.
Вот где пользовательские объекты извлекаются и добавляются в программу просмотра в виде чипов:
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Integer selectedUser = mMeeting.getUsers().get(position);
String selectedUserString = String.valueOf(selectedUser);
FirebaseFirestore db = FirebaseFirestore.getInstance();
String user = FirebaseAuth.getInstance().getCurrentUser().getUid();
DocumentReference userDocRec = db.collection("users/"+user+"/clients").document(selectedUserString);
userDocRec.get()
.addOnSuccessListener((documentSnapshot) -> {
if (documentSnapshot.exists()) {
User thisUser = documentSnapshot.toObject(User.class);
String name = String.valueOf(thisUser.getFirstName()
+ " " + String.valueOf(thisUser.getSurName()));
String dateOfBirth = thisUser.getDateOfBirth();
Chip chip = ((Chip) holder.itemView);
chip.setChipText(name);
chip.setVisibility(View.VISIBLE);
chip.setChecked(mMeeting.getAttended().contains(selectedUser));
chip.setOnCloseIconClickListener(view -> {
Toast.makeText(mContext, name + " - DOB: " + dateOfBirth, Toast.LENGTH_SHORT).show();
});
userMap.put(position, thisUser);
}
}
).addOnFailureListener((e) -> {
Toast.makeText(mContext, "Cannot load user", Toast.LENGTH_SHORT).show();
}
);
Я попробовал довольно хакерское решениепри этом представления адаптера и рециркулятора перезагружаются при каждом взаимодействии с функцией поиска, а цикл for заполняет фишки только в том случае, если имя пользователя соответствует или включает в себя поисковый запрос:
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
searchFilter = s;
AttendanceAdapter2 adapter = new AttendanceAdapter2(mMeeting, mContext,
(m) -> ((Callback<Meeting>) getActivity()).update(m));
recyclerView.setAdapter(adapter);
return false;
}
@Override
public boolean onQueryTextChange(String s) {
searchFilter = s;
AttendanceAdapter2 adapter = new AttendanceAdapter2(mMeeting, mContext,
(m) -> ((Callback<Meeting>) getActivity()).update(m));
recyclerView.setAdapter(adapter);
return false;
}
});
if (InterventionAttendanceFragment.searchFilter == "" ||
name.toLowerCase().contains(InterventionAttendanceFragment.searchFilter.toLowerCase())){
Chip chip = ((Chip) holder.itemView);
chip.setChipText(name);
chip.setVisibility(View.VISIBLE);
chip.setChecked(mMeeting.getAttended().contains(selectedUser));
chip.setOnCloseIconClickListener(view -> {
Toast.makeText(mContext, name + " - DOB: " + dateOfBirth, Toast.LENGTH_SHORT).show();
});
}
Это не лучшее решение, иочень ресурсоемкий, он проходит через Firebase каждый раз, а также оставляет пробелы в обзоре переработчиков для чипов, которые не соответствуют поисковому запросу.
Я нашел несколько хороших решений, но они полагаются на«пользователи» заполняются через список, и в связи с существующей инфраструктурой и характером приложенияКатион, я не могу изменить это слишком сильно, чтобы начать работать со списками, а не с базами данных:
Как отфильтровать RecyclerView с помощью SearchView
https://www.androidhive.info/2017/11/android-recyclerview-with-search-filter-functionality/
Любая помощь или указатели, а также возможные альтернативные решения или библиотеки приветствуются!
В настоящее время работает Android Studio 3.1.4