简体   繁体   English

搜索视图抛出异常(空 Object 参考)

[英]Search View throwing exception (Null Object Reference)

I have a fragment that uses a FragmentPagerAdapter and loads 2 other fragments with two recycler views.我有一个使用 FragmentPagerAdapter 的片段并使用两个回收器视图加载 2 个其他片段。 I'm trying to filter the items of the recycler views based on the text typed in the searchView.我正在尝试根据在 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).我有以下用于搜索功能的代码(我正在为两个片段实现相同的逻辑,即 ListOneFragment 和 ListTwoFragment,它们具有各自的 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) XML :(具有视图 Pager 和 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.我正在尝试使用 searchView 而不引入其他仅用于搜索的活动。 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/ )这是一个示例( 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.如果我在这里是正确的,那么您的 searchview 不在您的ListOneFragment中,这就是为什么给您一个 null 异常的原因,因为 search_view 不在其布局中。 To fix that, one of the ways, is to have the appbar/searchview inside your ListOneFragment and ListTwoFragment .要解决这个问题,其中一种方法是将 appbar/searchview 放在ListOneFragmentListTwoFragment中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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