简体   繁体   中英

Search View throwing exception (Null Object Reference)

I have a fragment that uses a FragmentPagerAdapter and loads 2 other fragments with two recycler views. I'm trying to filter the items of the recycler views based on the text typed in the searchView. I'm not using an individual search Activity, rather, I'm trying to use a filter for both the recycler views.

I have the following code for the search functionality (I'm implementing the same logic for both the Fragments namely ListOneFragment and ListTwoFragment which have their respective recycleView).

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
                }
            })

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: (common fragment which has view Pager with the search view in App Bar)

<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>

But I'm getting the following exception:

java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.appcompat.widget.SearchView.setOnQueryTextListener(androidx.appcompat.widget.SearchView$OnQueryTextListener)' on a null object reference

I'm trying to use the searchView without introducing another activity just for the search. This one works perfectly for a single fragment with one recycler view. Here's an example ( https://johncodeos.com/how-to-add-search-in-recyclerview-using-kotlin/ )

I will try to answer, hopefully I will be able to help.

It is not clear to me but I guess the fragment code shown is one of the ones that you shown in your viewpager, right? If I am correct here, your searchview is not in your ListOneFragment that is why you are given a null exception as the search_view is not in its layout. To fix that, one of the ways, is to have the appbar/searchview inside your ListOneFragment and ListTwoFragment .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM