简体   繁体   English

使用 ActionBar 中的 SearchView 小部件和片段

[英]Use the SearchView widget in ActionBar and a fragment

I'm trying to use the SearchView widget to filter the data from a RecyclerView.我正在尝试使用 SearchView 小部件来过滤来自 RecyclerView 的数据。 In an activity, it works like a charm.在一项活动中,它就像一个魅力。 However, in a fragment, the callbacks are not fired.但是,在片段中,不会触发回调。

Here is my fragment:这是我的片段:

class CowListFragment : Fragment(), SearchView.OnQueryTextListener {

    private val adapter = CowAdapter()

    private val args: CowListFragmentArgs by navArgs()

    private val viewModel: CowListViewModel by viewModels {
        InjectorUtils.provideCowViewModelFactory(this, args.livestockId)
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val binding = FragmentCowListBinding.inflate(inflater, container, false)
        context ?: return binding.root

        binding.cowRecyclerView.adapter = adapter
        subscribeUi(adapter)
        setHasOptionsMenu(true)

        return binding.root
    }

    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        inflater.inflate(R.menu.menu_cow_list, menu)
        val searchItem = menu.findItem(R.id.search_cow)
        val searchView = searchItem.actionView as SearchView
        searchView.setOnQueryTextListener(this)
    }

    private fun subscribeUi(adapter: CowAdapter) {
        viewModel.cows.observe(viewLifecycleOwner) { cows ->
            adapter.submitList(cows)
        }
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
            R.id.search_cow -> {
                true
            }
            else -> super.onOptionsItemSelected(item)
        }
    }

    override fun onQueryTextSubmit(query: String?): Boolean {
        query?.let { viewModel.filter(it) }
        return true
    }

    override fun onQueryTextChange(query: String?): Boolean {
        query?.let { viewModel.filter(it) }
        return true
    }
}

Here is my fragment layout:这是我的片段布局:

<?xml version="1.0" encoding="utf-8"?>

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

    <androidx.appcompat.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">

        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/app_bar_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:fitsSystemWindows="true"
            android:theme="@style/Theme.Bcs.AppBarOverlay">

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="@android:color/transparent"
                app:contentInsetStartWithNavigation="0dp"
                app:layout_collapseMode="pin"
                app:menu="@menu/menu_cow_list"
                app:navigationIcon="@drawable/ic_detail_back"
                app:titleTextColor="?attr/colorOnSurface" />

        </com.google.android.material.appbar.AppBarLayout>

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/cow_recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clipToPadding="false"
            android:paddingStart="@dimen/card_side_margin"
            android:paddingTop="@dimen/header_margin"
            android:paddingEnd="@dimen/card_side_margin"
            app:layoutManager="androidx.recyclerview.widget.StaggeredGridLayoutManager"
            app:spanCount="@integer/grid_columns"
            tools:context=".MainActivity"
            tools:listitem="@layout/list_item_cow" />
    </androidx.appcompat.widget.LinearLayoutCompat>
</layout>

And the menu:和菜单:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/search_cow"
        android:icon="@drawable/ic_search"
        android:title="@string/search_title"
        app:actionViewClass="androidx.appcompat.widget.SearchView"
        app:showAsAction="ifRoom|collapseActionView" />

</menu>

Interesting thing: If I breakpoint the constructor in the SearchView class, I see that multiple instances are created.有趣的事情:如果我在 SearchView class 中对构造函数进行断点,我会看到创建了多个实例。 It seems that the SearchView I add the listeners to is not the correct one.似乎我添加侦听器的 SearchView 不是正确的。

You can get the full code of the project here: Github link https://github.com/Christian-Adventiel/body-condition-score-mobile您可以在此处获取项目的完整代码: Github 链接https://github.com/Christian-Adventiel/body-condition-score-mobile

Any help would be really appreciated.任何帮助将非常感激。 Thanks!谢谢!

Adding this in the onCreateView function solved the issue:在 onCreateView function 中添加这个解决了这个问题:

(activity as AppCompatActivity).setSupportActionBar(binding.toolbar)

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

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