Исключение выдачи представления поиска (ссылка на нулевой объект) - PullRequest
0 голосов
/ 09 июля 2020

У меня есть фрагмент, который использует FragmentPagerAdapter и загружает 2 других фрагмента с двумя представлениями ресайклера. Я пытаюсь отфильтровать элементы представлений ресайклера на основе текста, введенного в searchView. Я не использую отдельное действие поиска, скорее, я пытаюсь использовать фильтр для обоих представлений ресайклера.

У меня есть следующий код для функции поиска (я реализую тот же logi c для обоих фрагментов, а именно 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/)

1 Ответ

1 голос
/ 09 июля 2020

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

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

...