Я тоже столкнулся с этой проблемой, решение, которое я нашел, это не фильтровать таблицу путем удаления элементов. Но отфильтрованные статьи я установил высоту на 0. Таким образом я сохраню позиции.
Код написан на kotlin, если вы не можете перевести его на java, скажите мне, и я вам помогу.
Шаг 1:
Добавьте это расширение (или переведите его в метод Java):
var View.isRemovedHeight: Boolean
get() {
return this.height == 0
}
set(value) {
if (value) {
val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0)
this.layoutParams = params
} else {
val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
this.layoutParams = params
}
}
Шаг 2:
Добавьте это в свой адаптер
//Filtering implementation
private var textFilter: String = ""
private val filteredItems: ArrayList<Items> = ArrayList()
А это:
// Filtering implementation
fun filter(text: String) {
textFilter = text.toLowerCase()
filteredCustomer.clear()
filteredCustomer.addAll(items.filter { it.name.toLowerCase().contains(textFilter) || it.address.toLowerCase().contains(textFilter) || it.phone.toLowerCase().contains(textFilter) })
notifyDataSetChanged()
}
fun notifyFilteringDataChanged() {
filteredCustomer.addAll(items)
filter(text = textFilter)
notifyDataSetChanged()
}
Первый метод - это логика для фильтрации, второй метод - обновить повторный цикл. Лучше всего было сделать переопределение метода notifyDataSetChanged, но мы не можем, потому что это последний метод. Поэтому я создал пользовательский notifyDataChanged
Шаг 3:
В макете XML поместите идентификатор в макет, потому что мы удалим его размер и установим его в 0
.
//Filtering implementation
val item = items[position]
holder.container.isRemovedHeight = !filteredItems.contains(item)
isRemovedHeight - это расширение, указанное выше, но для Java вы должны вызвать переведенный метод
В вашей деятельности. Когда бы вы ни захотели обновить данные в представлении повторного использования, используйте метод notifyFilteringDataChanged (), чтобы все обновлялось, например:
adapter.notifyFilteringDataChanged()
У вас, администратор, называйте этот метод:
adapter.filter(s.toString())
Извините за мой английский, надеюсь, он вам помог
Java
Шаг 1:
public boolean removeHeight(View view, boolean isRemoved) {
if(isRemoved) {
LayoutParams params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
view.setLayoutParams(params);
} else {
LayoutParams params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
view.setLayoutParams(params);
}
return isRemoved;
}
Шаг 2:
private String textFilter = "";
private ArrayList<Item> filteredItems = ArrayList();
И
public void filter(String text){
textFilter = text.toLowerCase();
filteredCustomer.clear();
filteredCustomer.addAll(items.stream().filter(i -> i.name.toLowerCase().contains(textFilter)));
notifyDataSetChanged();
}
public void notifyFilteringDataChanged(){
filteredCustomer.addAll(items);
filter(textFilter);
notifyDataSetChanged();
}
Шаг 3:
Item item = items.get(position);
removeHeight(holder.container, !filteredItems.contains(item));
И
adapter.notifyFilteringDataChanged();
И
adapter.filter(s.toString());