Сбой mutableList данных адаптера при изменении - PullRequest
0 голосов
/ 09 июля 2019

Я делаю фильтр SearchView для RecyclerView, в моем объекте Filter, в забавном «publishResults», мое приложение аварийно завершает работу, потому что я пытаюсь изменить mutableListOf, но data.clear () и data.addAll() вызывает ошибку

Кажется, что каждая модификация списка приводит к сбою приложения, я никогда не видел эту ошибку, несмотря на все остальные списки, которые я пытался изменить.Я думаю, что проблема в том, что он используется recyclerView, но я понятия не имею, почему, я ничего не нахожу в интернете и тем более на языке котлин.Также кажется, что существует большая проблема при попытке привести results?.values к Коллекции.

вот мой полный код адаптера

class SmallCatchAdapter(val clickListener: FishModelListener) : RecyclerView.Adapter<SmallCatchAdapter.ViewHolder>(), Filterable {

var data = mutableListOf<FishModel>()
    set(value) {
        field = value
        notifyDataSetChanged()
    }

var dataFull = listOf<FishModel>()

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    return ViewHolder.from(parent)
}

override fun getItemCount() = data.size

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    val item = data[position]
    holder.bind(item, clickListener)
}

class ViewHolder private constructor(val binding: ItemListSmallCatchBinding): RecyclerView.ViewHolder(binding.root) {
    fun bind(item : FishModel, clickListener: FishModelListener) {
        binding.fishModel = item
        binding.clickListener = clickListener
        binding.executePendingBindings()
    }

    companion object{
        fun from(parent: ViewGroup): ViewHolder {
            val layoutInflater = LayoutInflater.from(parent.context)
            val binding = ItemListSmallCatchBinding.inflate(layoutInflater, parent, false)

            return ViewHolder(binding)
        }
    }

}

override fun getFilter(): Filter {
    return fishListFilter
}

private val fishListFilter = object : Filter() {
    override fun performFiltering(constraint: CharSequence?): FilterResults {
        val dataFiltered = mutableListOf<FishModel>()
        if (constraint == null || constraint.isEmpty()) {
            dataFiltered.addAll(dataFull)
        } else {
            val filterPattern: String = constraint.toString().toLowerCase().trim()
            for (item in dataFull) {
                if(item.name.toLowerCase().contains(filterPattern)) {
                    dataFiltered.add(item)
                }
            }
        }
        val results = FilterResults()
        results.values = dataFiltered
        return results
    }

    override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
        data.clear()
        data.addAll(results?.values as MutableList<FishModel>)
        notifyDataSetChanged()
    }
}

}

class FishModelListener(val clickListener: (fishModelId: Int) -> Unit) {
    fun onClick(fishModel: FishModel) = clickListener(fishModel.speciesID)

}

Где он падает

override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
            data.clear()
            data.addAll(results?.values as Collection<FishModel>)
            notifyDataSetChanged()
        }

Ошибка:

java.lang.UnsupportedOperationException
    at java.util.AbstractList.remove(AbstractList.java:161)
    at java.util.AbstractList$Itr.remove(AbstractList.java:374)
    at java.util.AbstractList.removeRange(AbstractList.java:571)
    at java.util.AbstractList.clear(AbstractList.java:234)

Все работало хорошо, прежде чем я реализовал эту функцию, теперь я также заметил, что эта ошибка как-то перепуталась с моим Room Query, один (и только один) моего coroutineScope никогда не запускается, все остальное в порядке

(извините за ошибки, я не англичанин)

1 Ответ

0 голосов
/ 09 июля 2019

Вместо использования данных внутри onBindViewHolder вы должны создать другую переменную списка и использовать ее

var filterList : mutableListOf<FishModel>()

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    val item = filterList[position]
    holder.bind(item, clickListener)
}

Для фильтра, на котором я показываю некоторые ссылки, выполните действия, аналогичные приведенным ниже:

    private val customFilter: Filter = object : Filter() {
        override fun performFiltering(constraint: CharSequence): FilterResults {
            filterList =
                if (constraint.isEmpty()) {
                    items.toMutableList()
                } else {
                    items.filter {
                        it.name.contains(constraint, true) ||
                                it.name == constraint ||
                                it.price.toString() == constraint
                    }
                        .toMutableList()
                }

            if (sortByPV) {
                filterList.sortByDescending { it.pointValue }
            }

            return FilterResults().apply {
                values = filterList
                count = filterList.size
            }
        }

        override fun publishResults(constraint: CharSequence, results: FilterResults) {
            notifyDataSetChanged()
        }
    }

    override fun getFilter(): Filter = customFilter
    override fun getItemCount() = filterList.size

Здесь вам может потребоваться обновить ваш код соответствующим образом для слушателя щелчка элемента.

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