Исключение выдачи Search View (ссылка на нулевой объект)

У меня есть фрагмент, который использует FragmentPagerAdapter и загружает 2 других фрагмента с двумя представлениями переработчика. Я пытаюсь отфильтровать элементы представлений ресайклера на основе текста, введенного в 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/)


person Anirudh Ganesh    schedule 09.07.2020    source источник


Ответы (1)


Постараюсь ответить, надеюсь смогу помочь.

Мне непонятно, но я предполагаю, что показанный код фрагмента является одним из тех, которые вы показали в своем пейджере, верно? Если я здесь прав, вашего представления поиска нет в вашем ListOneFragment, поэтому вам предоставляется нулевое исключение, поскольку представление search_view отсутствует в его макете. Чтобы это исправить, одним из способов является размещение панели приложений/поиска внутри ваших ListOneFragment и ListTwoFragment.

person Henrique Vasconcellos    schedule 09.07.2020
comment
Да. У меня его нет во фрагментах ListOne и ListTwo. У меня есть общая панель приложений для фрагмента, который загружает два других фрагмента с помощью View Pager. Итак, мне нужно включить 2 просмотра поиска? Я хотел оставить только один, но я попробую. - person Anirudh Ganesh; 09.07.2020
comment
вы можете сделать это разными способами. Вы можете вызвать search_view в своем фрагменте commom, который раздувает ваш viewpager. - person Henrique Vasconcellos; 09.07.2020
comment
Но у меня есть 2 адаптера представления ресайклера, которые я использую для передачи значения фильтру. Поэтому я использую его в общем фрагменте, я не знаю, как я буду поддерживать один адаптер для обоих представлений. - person Anirudh Ganesh; 09.07.2020
comment
Я не понял вашего последнего комментария. Можно поподробнее?! - person Henrique Vasconcellos; 09.07.2020
comment
Содержимое адаптера представления ресайклера необходимо для передачи фильтру. Итак, у меня есть 2 представления ресайклера, и если я использую searchView в общем фрагменте, я не знаю, из какого представления ресайклера мне нужно фильтровать. Есть ли способ получить данные от адаптера пейджера, чтобы, возможно, я мог динамически видеть, на какой вкладке находится пользователь, и соответствующим образом фильтровать результаты. Но на данный момент, как вы упомянули, представление поиска по обоим отдельным фрагментам пока работает нормально. - person Anirudh Ganesh; 09.07.2020
comment
Ясно, хорошо, если вы собираетесь сделать это из commom, я думаю, вам нужно будет прослушивать изменение страницы на вашем пейджере и соответствующим образом передавать фильтр. В любом случае, все ли теперь работает так, как ожидалось? - person Henrique Vasconcellos; 10.07.2020
comment
Давайте продолжим обсуждение в чате. - person Anirudh Ganesh; 10.07.2020
comment
видимо ссылка в чате битая. Но проблема существует. Даже если я использую отдельные представления поиска, я получаю исключение нулевого указателя. Если я использую его в одном фрагменте без адаптеров страниц, то он работает нормально. - person Anirudh Ganesh; 07.11.2020