无法将“null”转换为非空类型kotlin.collections.List - kotlin

3

我正在尝试在RecyclerView中添加可过滤搜索功能,但是应用程序崩溃并出现以下错误:

kotlin.TypeCastException: 无法将null转换为非空类型kotlin.collections.List at com.kabelash.movies.ui.PostListAdapter$searchFilter$1.publishResults(PostListAdapter.kt:87) at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:284) at android.os.Handler.dispatchMessage(Handler.java:107) at 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()
        }
    }
}

如果你需要其他的class文件,请让我知道。有人能帮我解决这个问题吗?


看起来你的 postListFiltered = (results.values as List<Data>) 中的 result.values 是空的,这就是导致程序崩溃的原因。postListFiltered 是不可为空的。 - ror
这个回答解决了你的问题吗?什么是NullPointerException,我该如何修复它?(https://dev59.com/GnVC5IYBdhLWcg3wqzLV) - a_local_nobody
3
到目前为止,所有的答案都没有解释 results.values 怎么可能为空。过滤器的实现非常明显地总是会分配一个非空的值。你可以通过 postListFiltered = (results.values as List<Data>?).orEmpty() 来避免立即报错,但这可能掩盖了你仍然需要解决的其他错误。 - Tenfour04
你的日志中是否包含标签为“Filter”且消息为“在performFiltering()期间发生异常!”的警告? - Nitrodon
@Tenfour04 我明白这不是同一个异常或原因。但是OP试图将null转换为某些不期望null的内容,这篇文章提供了各种不同的原因,即1)为什么某些东西可能为空,2)如何处理事物为空,我认为这对OP来说是有用和相关的,因为堆栈跟踪已经指向了正确的方向。 - a_local_nobody
1
@Tenfour04 的 postListFiltered = (results.values as List<Data>?).orEmpty() 实际上是一个答案! - Gueorgui Obregon
3个回答

1
这一行是: results.values as List<Data> results.values 是 null,你试图让它成为非空列表,但它无法实现。

0

在执行强制类型转换之前,您需要执行空值检查,请按以下方式修改您的pulishResults方法。

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

0
正如其他两个答案所指出的那样,您的results.values是空的。但是代码清楚地显示,从performFiltering返回的FilterResults始终具有非空的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属性是否已初始化或显式初始化为空列表来修复它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接