【问题标题】:Add functioning SearchView to one specific Fragment将功能 SearchView 添加到一个特定的 Fragment
【发布时间】:2019-12-29 16:46:35
【问题描述】:

我有一个片段,我想在其中添加一个 SearchView。我已经在菜单中找到了它,它的可点击和所有内容,但我发现的每个实际搜索内容的指南要么已过时,要么不完全符合我的需要。

这是我的片段

    class ViewFragment : Fragment () {

    override fun onCreateView(inflater: LayoutInflater,container: ViewGroup?,
savedInstanceState: Bundle?
    ): View? {
        val binding: ViewFragmentBinding = DataBindingUtil.inflate(
            inflater, R.layout.view_fragment, container, false)

        val application = requireNotNull(this.activity).application

        setHasOptionsMenu(true)
        binding.setLifecycleOwner(this)

        viewFragmentViewModel.navigateToEdit.observe(this, Observer {translation ->
            translation?.let {
                this.findNavController().navigate(
                    ViewFragmentDirections
                        .actionViewFragmentToEditFragment(translation)
                )
                viewFragmentViewModel.onEditNavigated()
            }
        })

        val adapter = TranslationAdapter(TranslationListener { translationID ->
            viewFragmentViewModel.onTranslationClicked(translationID)
        })
        binding.translationList.adapter = adapter

        viewFragmentViewModel.translations.observe(viewLifecycleOwner, Observer {
            it?.let {
                adapter.submitList(it)
            }
        })

        return binding.root
    }

    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater){
        inflater.inflate(R.menu.search_menu, menu)
        super.onCreateOptionsMenu(menu, inflater)

    }

这是我的搜索菜单

<menu 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:layout_width="match_parent"
    android:layout_height="match_parent">


    <item
        android:id="@+id/action_search"
        android:icon="@android:drawable/ic_menu_search"
        app:showAsAction="always|collapseActionView"
        app:actionViewClass="android.widget.SearchView"
        android:title="Search"/>
</menu>

谁能告诉我如何设置所有内容,以便我可以访问用户输入的搜索字符串并将新列表提交到 RecycleView?或者只是指出我正确的方向!

提前谢谢你!

编辑:这是更新。我有一个 MutableLiveData 我在其中放置查询并观察它,以便我可以对它的观察功能采取行动。我在要更新的 ViewModel 中有一个变量 translationList。

class ViewFragment : Fragment (), SearchView.OnQueryTextListener {


private var searchText = MutableLiveData<String>()

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {

...

    val adapter = TranslationAdapter(TranslationListener { translationID ->
        viewFragmentViewModel.onTranslationClicked(translationID)
    })
    binding.translationList.adapter = adapter

    viewFragmentViewModel.translations.observe(viewLifecycleOwner, Observer {
        it?.let {
            adapter.submitList(it)
        }
    })

    searchText.observe(this, Observer {searchString ->
        searchString?.let {
            if(searchString == ""){
                adapter.submitList(viewFragmentViewModel.translations.value)
            }
            else{
                adapter.submitList(viewFragmentViewModel.searchTranslations(searchString))
            }

        }
    })

}

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater){
    inflater.inflate(R.menu.search_menu, menu)

    val menuItem = menu.findItem(R.id.action_search)
    val searchView = menuItem.actionView as SearchView
    searchView.setOnQueryTextListener(this)
    super.onCreateOptionsMenu(menu, inflater)
}

override fun onQueryTextChange(newText: String?): Boolean {

    searchText.value = newText
    return true
}

override fun onQueryTextSubmit(query: String?): Boolean {
    return false
}

}

对于闭包,由于我已经有一个列表,其中包含我想要搜索的数据库中的所有对象,因此只需使用过滤器浏览该列表就更容易了。

【问题讨论】:

    标签: android android-fragments kotlin search android-recyclerview


    【解决方案1】:

    步骤 - 1: 在您的 ViewFragment 中实现 SearchView.OnQueryTextListener

    class ViewFragment : Fragment(), SearchView.OnQueryTextListener {
    
        ...
    
        override fun onQueryTextSubmit(query: String?): Boolean {
            return false
        }
    
        override fun onQueryTextChange(newText: String?): Boolean {
    
            //Do your operation here
    
            return true
        }
    }
    

    步骤 - 2: 从菜单中获取 SearchView 并使用侦听器进行初始化

    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        inflater.inflate(R.menu.search_menu, menu)
    
        val meniItem = menu?.findItem(R.id.action_search)
        val searchView = meniItem?.actionView as SearchView?
        searchView?.setOnQueryTextListener(this)
    
        super.onCreateOptionsMenu(menu, inflater)
    }
    

    第 3 步:onQueryTextChange 内部获取您的搜索查询并执行操作

    更新:如下更改您的实现:

    fun searchTranslations(searchString: String) : List<Translation>? {
        return database.getTranslationsBySearch(searchString).value
    }
    

    和道

    @Query("SELECT * FROM word_translation_table WHERE word_ger LIKE '% :string %'  OR word_es LIKE '% :string %' ")
    fun getTranslationsBySearch(string: String): LiveData<List<Translation>>
    

    【讨论】:

    • 非常感谢!这对我帮助很大。我可以启动一个新的查询,从我的数据库中获取一个新的 LiveData>,但是当我用新的对象覆盖旧的 LiveData 对象时,屏幕不会更新。你知道为什么会这样吗?
    • 需要查看viewFragmentViewModel.searchTranslations。也添加这个
    • 我想我缩小了房间数据库查询的问题范围。它只是返回一个空列表。将查询添加到问题中。
    • 那行不通。 “未使用的参数”如果我把 '% :string %' 放在那里,它不会得到字符串。我已经尝试过类似的事情了。
    猜你喜欢
    • 1970-01-01
    • 2016-03-21
    • 1970-01-01
    • 1970-01-01
    • 2018-12-11
    • 2020-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多