Android 搜索视图引发异常(空对象引用)
我有一个片段,它使用FragmentPagerAdapter并加载另外两个带有两个回收器视图的片段。我正试图根据在searchView中键入的文本筛选recycler视图中的项目。我并没有使用单独的搜索活动,相反,我尝试对两个回收者视图使用一个过滤器 我为搜索功能编写了以下代码(我为这两个片段实现了相同的逻辑,即ListOneFragment和ListTwoFragment,它们都有各自的recycleView) 片段:Android 搜索视图引发异常(空对象引用),android,android-recyclerview,android-viewpager,searchview,android-pageradapter,Android,Android Recyclerview,Android Viewpager,Searchview,Android Pageradapter,我有一个片段,它使用FragmentPagerAdapter并加载另外两个带有两个回收器视图的片段。我正试图根据在searchView中键入的文本筛选recycler视图中的项目。我并没有使用单独的搜索活动,相反,我尝试对两个回收者视图使用一个过滤器 我为搜索功能编写了以下代码(我为这两个片段实现了相同的逻辑,即ListOneFragment和ListTwoFragment,它们都有各自的recycleView) 片段: class ListOneFragment : Fragment() {
class ListOneFragment : Fragment() {
lateinit var adapter: ListOneRecyclerViewAdapter
lateinit var listonerv: RecyclerView
viewModel.getListOne().observe(viewLifecycleOwner,Observer {
recyclerView.apply {
layoutManager = LinearLayoutManager(context,RecyclerView.VERTICAL, false)
adapter = ListOneRecyclerViewAdapter(it, mViewModel)
}
adapter = recyclerView.adapter as ListOneRecyclerViewAdapter
})
listonerv = findViewById(R.id.recyclerView)
listone_search.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
//------------------------The exception is being thrown for the line above------------------------
override fun onQueryTextSubmit(query: String?): Boolean {
return false
}
override fun onQueryTextChange(newText: String?): Boolean {
adapter.filter.filter(newText)
return false
}
})
class ListOneRecyclerViewAdapter(
private val firstList : ArrayList<ListOne>,
private val viewModel: ListViewModel
): RecyclerView.Adapter<ListOneViewHolder>(), Filterable {
var filterList = ArrayList<ListOne>()
init{
filterList = firstList //so that when the search bar is empty, all items are populated
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
ListOneViewHolder(viewModel,
LayoutInflater.from(parent.context).inflate(R.layout.item_one, parent, false))
override fun getItemCount() = filterList.size
override fun onBindViewHolder(holder: ListOneViewHolder, position: Int) {
holder.bind(filterList[position])
}
override fun getFilter(): Filter {
Log.d("Test", "Inside getFilter")
return object : Filter() {
override fun performFiltering(constraint: CharSequence?): FilterResults {
val charSearch = constraint.toString()
if (charSearch.isEmpty()) {
Log.d("Test","char is empty")
filterList = firstList
} else {
Log.d("Test","something typed")
val resultList = ArrayList<ListOne>()
for (row in firstList) {
if (row.name.toLowerCase(Locale.ROOT).contains(charSearch.toLowerCase(Locale.ROOT))) {
resultList.add(row)
}
}
filterList = resultList
Log.d("Test",filterList.toString())
}
val filterResults = FilterResults()
filterResults.values = filterList
Log.d("Filter",filterResults.values.toString())
return filterResults
}
@Suppress("UNCHECKED_CAST")
override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
filterList = results?.values as ArrayList<ListOne>
Log.d("Publish",filterList.toString())
notifyDataSetChanged()
}
}
}
回收服务适配器:
class ListOneFragment : Fragment() {
lateinit var adapter: ListOneRecyclerViewAdapter
lateinit var listonerv: RecyclerView
viewModel.getListOne().observe(viewLifecycleOwner,Observer {
recyclerView.apply {
layoutManager = LinearLayoutManager(context,RecyclerView.VERTICAL, false)
adapter = ListOneRecyclerViewAdapter(it, mViewModel)
}
adapter = recyclerView.adapter as ListOneRecyclerViewAdapter
})
listonerv = findViewById(R.id.recyclerView)
listone_search.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
//------------------------The exception is being thrown for the line above------------------------
override fun onQueryTextSubmit(query: String?): Boolean {
return false
}
override fun onQueryTextChange(newText: String?): Boolean {
adapter.filter.filter(newText)
return false
}
})
class ListOneRecyclerViewAdapter(
private val firstList : ArrayList<ListOne>,
private val viewModel: ListViewModel
): RecyclerView.Adapter<ListOneViewHolder>(), Filterable {
var filterList = ArrayList<ListOne>()
init{
filterList = firstList //so that when the search bar is empty, all items are populated
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
ListOneViewHolder(viewModel,
LayoutInflater.from(parent.context).inflate(R.layout.item_one, parent, false))
override fun getItemCount() = filterList.size
override fun onBindViewHolder(holder: ListOneViewHolder, position: Int) {
holder.bind(filterList[position])
}
override fun getFilter(): Filter {
Log.d("Test", "Inside getFilter")
return object : Filter() {
override fun performFiltering(constraint: CharSequence?): FilterResults {
val charSearch = constraint.toString()
if (charSearch.isEmpty()) {
Log.d("Test","char is empty")
filterList = firstList
} else {
Log.d("Test","something typed")
val resultList = ArrayList<ListOne>()
for (row in firstList) {
if (row.name.toLowerCase(Locale.ROOT).contains(charSearch.toLowerCase(Locale.ROOT))) {
resultList.add(row)
}
}
filterList = resultList
Log.d("Test",filterList.toString())
}
val filterResults = FilterResults()
filterResults.values = filterList
Log.d("Filter",filterResults.values.toString())
return filterResults
}
@Suppress("UNCHECKED_CAST")
override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
filterList = results?.values as ArrayList<ListOne>
Log.d("Publish",filterList.toString())
notifyDataSetChanged()
}
}
}
我正在尝试使用searchView,而不只是为了搜索而引入其他活动。这一个非常适用于具有一个回收器视图的单个片段。下面是一个例子()我将尝试回答,希望我能提供帮助
我不清楚,但我猜显示的片段代码是您在viewpager中显示的片段代码之一,对吗?如果我在这里是正确的,您的searchview不在您的ListOneFragment中,这就是为什么您会得到一个空异常,因为search_视图不在其布局中。要解决这个问题,其中一种方法是在ListOneFragment和ListTwoFragment中使用appbar/searchview。Yes。我在ListOne和ListTwo片段中没有它。我有一个用于片段的通用应用程序栏,它使用视图寻呼机加载其他2个帧。所以我需要包含2个搜索视图?我只想保留一个,但我会尝试一下。你可以用很多方法来做到。您可以在commom片段中调用search_视图,该视图会使您的viewpager膨胀。但是我有两个recycler视图适配器,我正在使用它们将值传递给过滤器。所以我在公共片段中使用它,我不知道如何为这两个视图维护一个适配器。我不理解你的上一条评论。你能详细解释一下吗?!需要回收器视图适配器的内容才能将其传递到筛选器。所以我这里有两个回收器视图,如果我在公共片段中使用searchView,我不知道需要从哪个回收器视图中进行过滤。有没有一种方法可以从寻呼机适配器获取数据,这样我就可以动态地看到用户在哪个选项卡上,并相应地过滤结果。但就目前而言,正如您所提到的,两个单独片段的搜索视图目前运行良好。