null не может быть приведен к ненулевому типу kotlin.collections.List - kotlin

Я пытаюсь добавить фильтруемый поиск в RecyclerView. но приложение вылетает со следующей ошибкой:

kotlin.TypeCastException: значение null не может быть приведено к типу, отличному от null (Filter.java:284) в android.os.Handler.dispatchMessage(Handler.java:107) в android.os.Looper.loop(Looper.java:214)

Адаптер:

class PostListAdapter: RecyclerView.Adapter<PostListAdapter.ViewHolder>(), Filterable {
    private lateinit var postListFiltered:List<Data>
    private lateinit var postListFull:List<Data>

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val binding: ListItemBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.context), R.layout.list_item, parent, false)
        return ViewHolder(binding)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.bind(postListFiltered[position])
    }

    override fun getItemCount(): Int {
        return if(::postListFiltered.isInitialized) postListFiltered.size else 0
    }

    fun updatePostList(postList:List<Data>){
        this.postListFiltered = postList
        notifyDataSetChanged()
    }

    class ViewHolder(private val binding: ListItemBinding): RecyclerView.ViewHolder(binding.root){
        private val viewModel = MoviesViewModel()

        fun bind(post:Data){
            viewModel.bind(post)
            binding.viewModel = viewModel
        }

    }

    override fun getFilter(): Filter? {
        return searchFilter
    }

    private val searchFilter: Filter = object : Filter() {
        override fun performFiltering(constraint: CharSequence?): FilterResults? {
            val filteredList: MutableList<Data> = ArrayList()
            if (constraint == null || constraint.isEmpty()) {
                filteredList.addAll(postListFull)
            } else {
                val filterPattern = constraint.toString().toLowerCase().trim()
                for (item in postListFull) {
                    if (item.title.toLowerCase().contains(filterPattern) || item.genre.toLowerCase().contains(filterPattern)) {
                        filteredList.add(item)
                    }
                }

            }
            val results = FilterResults()
            results.values = filteredList
            return results
        }

        override fun publishResults(constraint: CharSequence?,results: FilterResults) {
            postListFiltered = (results.values as List<Data>)
            notifyDataSetChanged()
        }
    }
}

Если вам нужен какой-либо другой файл класса, пожалуйста, дайте мне знать. Может кто-нибудь, пожалуйста, помогите мне решить эту проблему?


person GK007    schedule 16.12.2019    source источник
comment
Похоже, что result.values ​​имеет значение null в вашем postListFiltered = (results.values as List<Data>) - это причина вашего сбоя. postListFiltered не может принимать значение NULL.   -  person ror    schedule 16.12.2019
comment
Отвечает ли это на ваш вопрос? Что такое исключение NullPointerException и как его исправить?   -  person a_local_nobody    schedule 16.12.2019
comment
Ни один из ответов пока не объясняет, как results.values может быть нулевым. Реализация фильтра очень четко всегда присваивает ему ненулевое значение. Вы должны быть в состоянии избежать непосредственной ошибки с postListFiltered = (results.values as List<Data>?).orEmpty(), но это, вероятно, маскирует какую-то другую ошибку, которую вам еще предстоит решить.   -  person Tenfour04    schedule 16.12.2019
comment
Включает ли ваш журнал предупреждение с тегом «Фильтр» и сообщение «Исключение произошло во время выполнения фильтрации()!» ?   -  person Nitrodon    schedule 16.12.2019
comment
@ Tenfour04 Я понимаю, что это не одно и то же исключение или причина. но OP пытается присвоить null чему-то, что не ожидает null, в этом посте приводятся различные причины: 1) почему что-то может быть null и 2) как обращаться с вещами, имеющими значение null, полагая, что это было бы полезно и актуально для ОП видит, что трассировка стека уже указывает им правильное направление   -  person a_local_nobody    schedule 16.12.2019
comment
@ Tenfour04 postListFiltered = (results.values ​​как List‹Data›?).orEmpty() на самом деле является ответом!   -  person Gueorgui Obregon    schedule 17.12.2019


Ответы (3)


Это строка: results.values as List<Data>

results.values имеет значение null, и вы говорите, что это ненулевой список, чего он не может сделать.

person TomH    schedule 16.12.2019

Вам нужно будет выполнить нулевую проверку перед выполнением приведения, измените метод pulishResults следующим образом.

   override fun publishResults(constraint: CharSequence?,results: FilterResults) {
                postListFiltered = if(results == null || results.values == null)
                                       ArrayList<Data>() 
                                   else
                                        results.values
                notifyDataSetChanged()
            }
person mightyWOZ    schedule 16.12.2019

Как правильно указывают два других ответа, ваш results.values равен нулю. Но код ясно показывает, что FilterResults, возвращаемый из performFiltering, всегда имеет ненулевое поле values. Как это могло произойти?

Краткий взгляд на исходный код Filter дает возможный ответ:

// Filter.RequestHandler.handleMessage(Message msg)

try {
    args.results = performFiltering(args.constraint);
} catch (Exception e) {
    args.results = new FilterResults();
    Log.w(LOG_TAG, "An exception occured during performFiltering()!", e);
}

Проще говоря, если performFiltering() выдает исключение, фильтр перехватывает исключение и использует пустой FilterResults вместо того, что в противном случае было бы возвращено. Трассировку стека для этого исключения можно найти в logcat.

Глядя на вашу функцию performFiltering, единственное исключение, которое выделяется, это UninitializedPropertyAccessException. Если это окажется вызванным исключением, вы можете исправить его, либо проверив, инициализировано ли свойство fullPostList, либо явно инициализировав его пустым списком.

person Nitrodon    schedule 16.12.2019