You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在RecyclerView列表中使用SearchView时应用崩溃,求排查解决

问题:SearchView导致应用启动失败,无法实现披萨餐厅搜索功能

我开发的应用用RecyclerView展示披萨餐厅信息(名称、位置、评分),想加SearchView按名称搜索,但每次运行都报SearchView相关错误,应用启动不了。查了官方文档和教程,反复检查代码还是解决不了。

以下是我的RV.Adapter代码:

class PizzaAdapter(private var PizzaList: List<Pizza>):
    RecyclerView.Adapter<PizzaAdapter.PizzaViewHolder>()
{
    private lateinit var listener: PizzaAdapterListener
    inner class PizzaViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val textViewName: TextView = itemView.findViewById(R.id.textViewName)
        val textViewLocation: TextView = itemView.findViewById(R.id.textViewLocation)
        val ratingBar: RatingBar = itemView.findViewById(R.id.ratingBar)
    } // end MyViewHolder

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PizzaViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.activity_current_pizza_palor_list, parent, false)
        return PizzaViewHolder(view)
    }

    override fun onBindViewHolder(holder: PizzaViewHolder, position: Int) {
        val pizza = PizzaList[position]
        holder.textViewName.text = pizza.name
        holder.textViewLocation.text = pizza.location
        holder.ratingBar.rating = pizza.rate!!?.toFloat()!!

    }

    override fun getItemCount(): Int {
        return PizzaList.size
    }

    fun setData(list: List<Pizza>) {
        PizzaList = list
        notifyDataSetChanged()
    }

    interface PizzaAdapterListener {
        fun onClick(position: Int)
    }

    fun getFilter(): Filter {
        return object : Filter() {
            override fun performFiltering(constraint: CharSequence?): FilterResults {
                val filteredList = mutableListOf<Pizza>()

                if (constraint == null || constraint.isEmpty()) {
                    filteredList.addAll(PizzaList)
                } else {
                    val filterPattern = constraint.toString().toLowerCase().trim()

                    for (item in PizzaList) {
                        if (item.name.toLowerCase().contains(filterPattern)) {
                            filteredList.add(item)
                        }
                    }
                }

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

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

    fun setOnItemClickListener(_listener: PizzaAdapterListener) {
        listener = _listener
    }
}
}
}

以下是使用SearchView的MainActivity代码:

class MainActivity : AppCompatActivity() {
private lateinit var recyclerViewPizza: RecyclerView
private lateinit var data : ArrayList<Pizza>
private lateinit var pizzaAdapter : PizzaAdapter
private lateinit var searchView : SearchView
@SuppressLint("MissingInflatedId")
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    recyclerViewPizza = findViewById<RecyclerView>(R.id.recyclerViewPizza)
    recyclerViewPizza.layoutManager = LinearLayoutManager(this)

    data = ArrayList<Pizza>()
    data.add(Pizza("Pizza Hut", "Deer Park", 3.1))
    data.add(Pizza("Papa Johns", "Deer Park", 3.9))
    data.add(Pizza("Richie's Pizza", "Commack", 4.4))
    data.add(Pizza("Domino's Pizza", "Deer Park", 4.2))

    val searchView = findViewById<SearchView>(R.id.searchView)

    searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
        override fun onQueryTextSubmit(query: String?): Boolean {
            return false
        }

        override fun onQueryTextChange(newText: String?): Boolean {
            filter(newText)
            return true
        }
    })
}

private fun filter(query: String?) {
    val filteredList = mutableListOf<Pizza>()
    if (query.isNullOrEmpty()) {
        filteredList.addAll(data)
    } else {
        val filterPattern = query.trim()
        for (item in data) {
            if (item.name.contains(filterPattern, true)) {
                filteredList.add(item)
            }
        }
    }
}

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
    val inflater = menuInflater
    inflater.inflate(R.menu.toolmenu, menu)
    return true
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.getItemId()) {
        R.id.add_item->{
            val intent = Intent(this@MainActivity, AddActivity::class.java)
            startActivity(intent)
            true
        }
        else -> super.onOptionsItemSelected(item)
    }
}
}

错误排查与修复方案

1. PizzaAdapter代码语法错误(直接导致启动失败)

  • getFilter()方法未正确闭合:publishResults方法结束后缺少},导致setOnItemClickListener被嵌套在Filter内部,触发语法错误。
  • ratingBar.rating = pizza.rate!!?.toFloat()!!存在冗余空安全操作,!!?是无效语法,替换为pizza.rate?.toFloat() ?: 0f(兼容rate为null的情况)。
  • 将PizzaList声明为MutableList<Pizza>,避免过滤时的类型转换异常。

修复后的PizzaAdapter:

class PizzaAdapter(private var pizzaList: MutableList<Pizza>) :
    RecyclerView.Adapter<PizzaAdapter.PizzaViewHolder>() {

    private lateinit var listener: PizzaAdapterListener

    inner class PizzaViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val textViewName: TextView = itemView.findViewById(R.id.textViewName)
        val textViewLocation: TextView = itemView.findViewById(R.id.textViewLocation)
        val ratingBar: RatingBar = itemView.findViewById(R.id.ratingBar)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PizzaViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.activity_current_pizza_palor_list, parent, false)
        return PizzaViewHolder(view)
    }

    override fun onBindViewHolder(holder: PizzaViewHolder, position: Int) {
        val pizza = pizzaList[position]
        holder.textViewName.text = pizza.name
        holder.textViewLocation.text = pizza.location
        holder.ratingBar.rating = pizza.rate?.toFloat() ?: 0f
    }

    override fun getItemCount(): Int {
        return pizzaList.size
    }

    fun setData(list: List<Pizza>) {
        pizzaList.clear()
        pizzaList.addAll(list)
        notifyDataSetChanged()
    }

    interface PizzaAdapterListener {
        fun onClick(position: Int)
    }

    fun getFilter(): Filter {
        return object : Filter() {
            override fun performFiltering(constraint: CharSequence?): FilterResults {
                val filteredList = mutableListOf<Pizza>()

                if (constraint == null || constraint.isEmpty()) {
                    filteredList.addAll(pizzaList)
                } else {
                    val filterPattern = constraint.toString().lowercase().trim()

                    for (item in pizzaList) {
                        if (item.name.lowercase().contains(filterPattern)) {
                            filteredList.add(item)
                        }
                    }
                }

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

            override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
                pizzaList = results?.values as MutableList<Pizza>
                notifyDataSetChanged()
            }
        }
    }

    fun setOnItemClickListener(_listener: PizzaAdapterListener) {
        listener = _listener
    }
}

2. MainActivity关键错误修复

  • 初始化并绑定适配器:之前未实例化pizzaAdapter也未设置给RecyclerView,导致列表无数据源,同时SearchView无法联动。
  • 移除局部变量覆盖:删除val searchView = findViewById<SearchView>(R.id.searchView)中的val,使用全局变量。
  • 联动适配器过滤逻辑:删除冗余的filter方法,直接调用适配器的getFilter().filter()更新列表。

修复后的MainActivity:

class MainActivity : AppCompatActivity() {
    private lateinit var recyclerViewPizza: RecyclerView
    private lateinit var data: ArrayList<Pizza>
    private lateinit var pizzaAdapter: PizzaAdapter
    private lateinit var searchView: SearchView

    @SuppressLint("MissingInflatedId")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        recyclerViewPizza = findViewById(R.id.recyclerViewPizza)
        recyclerViewPizza.layoutManager = LinearLayoutManager(this)

        data = ArrayList()
        data.add(Pizza("Pizza Hut", "Deer Park", 3.1))
        data.add(Pizza("Papa Johns", "Deer Park", 3.9))
        data.add(Pizza("Richie's Pizza", "Commack", 4.4))
        data.add(Pizza("Domino's Pizza", "Deer Park", 4.2))

        // 初始化适配器并绑定到RecyclerView
        pizzaAdapter = PizzaAdapter(data.toMutableList())
        recyclerViewPizza.adapter = pizzaAdapter

        searchView = findViewById(R.id.searchView)
        searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
            override fun onQueryTextSubmit(query: String?): Boolean {
                pizzaAdapter.getFilter().filter(query)
                return true
            }

            override fun onQueryTextChange(newText: String?): Boolean {
                pizzaAdapter.getFilter().filter(newText)
                return true
            }
        })
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.toolmenu, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
            R.id.add_item -> {
                startActivity(Intent(this@MainActivity, AddActivity::class.java))
                true
            }
            else -> super.onOptionsItemSelected(item)
        }
    }
}

3. 额外检查点

  • 确认activity_main.xml中存在R.id.searchView,如果SearchView在menu中,需在onCreateOptionsMenu中获取:
    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.toolmenu, menu)
        val searchItem = menu?.findItem(R.id.action_search)
        val searchView = searchItem?.actionView as SearchView
        searchView.setOnQueryTextListener(...)
        return true
    }
    
  • 确保Pizza数据类的字段定义正确,无空指针风险。

内容的提问来源于stack exchange,提问作者SRBeginnerDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 19:13:12