我有一个片段,它使用FragmentPagerAdapter并加载另外两个具有两个回收器视图的片段。我正在尝试根据searchView中键入的文本过滤回收器视图中的项目。我没有使用单独的搜索活动,相反,我尝试对两个回收器视图都使用过滤器。
我有下面的搜索功能代码(我为两个片段实现了相同的逻辑,即ListOneFragment和ListTwoFragment,它们有各自的recycleView(。
片段:
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
}
})
RecyclerViewAdapter:
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()
}
}
}
XML:(常见片段,具有Pager视图和应用程序栏中的搜索视图(
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".screens.first.ListOneFragment">
<include
layout="@layout/layout_background_image" />
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:navigationIcon="?homeAsUpIndicator"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
/>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicatorColor="@color/white"
app:tabIndicatorHeight="@dimen/_2sdp"
app:tabSelectedTextColor="@color/white" />
<androidx.appcompat.widget.SearchView
android:id="@+id/listone_search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textCursorDrawable="@null"
app:queryHint="@string/Search"
android:elevation="@dimen/_8sdp"
app:iconifiedByDefault="false"
app:queryBackground="@null"
app:layout_constraintTop_toBottomOf="@+id/appbar"
app:layout_constraintStart_toStartOf="parent"/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
但我得到了以下例外:
java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.appcompat.widget.SearchView.setOnQueryTextListener(androidx.appcompat.widget.SearchView$OnQueryTextListener)' on a null object reference
我正在尝试使用searchView,而不引入仅用于搜索的其他活动。这一个非常适用于具有一个回收器视图的单个片段。下面是一个例子(https://johncodeos.com/how-to-add-search-in-recyclerview-using-kotlin/)
我会尽力回答,希望我能提供帮助。
我不清楚,但我想显示的片段代码是你在viewpager中显示的代码之一,对吧?如果我在这里是正确的,那么您的searchview不在ListOneFragment中,这就是为什么您会得到一个null异常,因为search_view不在其布局中。要解决这个问题,其中一种方法是在ListOneFragment和ListTwoFragment中设置appbar/searchview。