菜单栏中和页面上的SearchView简单使用

1.预览

SearchView可以在菜单栏中,也可以单独放在页面上,下面分开实现(实现效果图如下:)

2.菜单栏中的SearchView

2.1新建一个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/app_bar_search"
        android:icon="@drawable/ic_search_black_24dp"
        android:title="Search"
        app:actionViewClass="android.widget.SearchView"
        app:showAsAction="always" />
</menu>

2.2在fragment中设置SearchView

  • onCraeteView中启用菜单
  • 重载onCreateOptionsMenu方法,设置监听事件
package com.example.ngsl.wordFragment

import android.os.Bundle
import android.util.Log
import android.view.*
import android.widget.SearchView
import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.GridLayoutManager
import com.example.ngsl.R
import com.example.ngsl.room.Word
import kotlinx.android.synthetic.main.word_fragment.*

class WordFragment : Fragment() {

    private lateinit var viewModel: WordViewModel
    private lateinit var filterWords: LiveData<List<Word>>
    private lateinit var wordFragmentAdapter: WordFragmentAdapter

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        //启用菜单栏
        setHasOptionsMenu(true)
        return inflater.inflate(R.layout.word_fragment, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        //创建适配器
        wordFragmentAdapter = WordFragmentAdapter()
        recycleView.apply {
            adapter = wordFragmentAdapter
            layoutManager = GridLayoutManager(requireContext(), 1)
        }

        //ViewModel
        viewModel = ViewModelProvider(this).get(WordViewModel::class.java)
        filterWords = viewModel.allWord
        filterWords.observe(viewLifecycleOwner, Observer {
            //为适配器提供数据
            wordFragmentAdapter.submitList(it)
        })

    //菜单栏相关
    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        super.onCreateOptionsMenu(menu, inflater)
        //添加菜单,R.menu.menu就是你上面创建的菜单文件
        inflater.inflate(R.menu.menu, menu)
        
        //获取SearchView
        val searchView = menu.findItem(R.id.app_bar_search).actionView as SearchView
        searchView.maxWidth = 900 //设置最大长度
        
        searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
        	//用户点击键盘“搜索键”事件
            override fun onQueryTextSubmit(query: String?): Boolean {
                return false
            }
			//用户输入内容发生改变事件
            override fun onQueryTextChange(newText: String?): Boolean {
                val pattern = newText?.trim() as String
                Log.d("myLog", pattern)
                filterWords.removeObservers(requireActivity())
                filterWords = viewModel.searchWords(pattern)
                filterWords.observe(requireActivity(), Observer {
                    wordFragmentAdapter.submitList(it)
                })
                return true
            }
        })
    }
}

菜单栏中的SearchView,GitHub源码链接:https://github.com/YDDUONG/NGSL-English(整个项目有很多组件,只看你需要的部分)

3.页面中的SearchView

3.1我们先画一个搜索图标

在drawable文件夹下创建一个xml文件(ic_search.xml),写入一下代码

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="24dp"
    android:width="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:fillColor="#000"
        android:pathData="M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z" />
</vector>

3.2添加布局

<SearchView
    android:id="@+id/searchView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="1dp"
    android:queryHint="Search Here"
    app:searchIcon="@drawable/ic_search" />

3.3SearchView设置(都在注释中了)

package com.example.gca.leftFragment.fragment

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.SearchView
import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.gca.R
import com.example.gca.adapter.SearchGarbageAdapter
import com.example.gca.room.garbageTable.Garbage
import kotlinx.android.synthetic.main.search_fragment.*

/**
 * A simple [Fragment] subclass.
 */
class SearchFragment : Fragment() {
    private lateinit var filteredGarbage: LiveData<List<Garbage>>

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.search_fragment, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        val searchViewModel = ViewModelProvider(
            this,
            ViewModelProvider.AndroidViewModelFactory(requireActivity().application)
        ).get(SearchViewModel::class.java)


        //适配器
        val searchGarbageAdapter = SearchGarbageAdapter() //适配器
        recyclerView.apply {
            adapter = searchGarbageAdapter
            layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
        }

        //观察
        filteredGarbage = searchViewModel.historyGarbageValue
        filteredGarbage.observe(this.viewLifecycleOwner, Observer {
            searchGarbageAdapter.submitList(it)
        })


        //!!!以下就是Search的设置(按需设置)
//        //设置搜索框直接展开显示。左侧有放大镜(在搜索框中) 右侧有叉叉 可以关闭搜索框
//        searchView.isIconified = false
//        //设置搜索框直接展开显示。左侧有放大镜(在搜索框外) 右侧无叉叉 有输入内容后有叉叉 不能关闭搜索框
//        searchView.isIconifiedByDefault = false
//        //设置搜索框直接展开显示。左侧有无放大镜(在搜索框中) 右侧无叉叉 有输入内容后有叉叉 不能关闭搜索框
//        searchView.onActionViewExpanded()
        //其他设置
//        searchView.isFocusableInTouchMode = true //设置触摸聚焦
//        searchView.requestFocus() //请求焦点
//        searchView.findFocus() //获取焦点
        
        //这几句就可以获得不错的效果
        searchView.onActionViewExpanded()
        searchView.isFocusable = true //设置输入框可聚集
        searchView.requestFocusFromTouch() //请求焦点

        //搜索栏监听
        searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
            //提交监听
            override fun onQueryTextSubmit(query: String): Boolean {
                return false
            }

            //内容发生改变
            override fun onQueryTextChange(newText: String): Boolean {
                val pattern = newText.trim()
                filteredGarbage.removeObservers(requireActivity())
                filteredGarbage = searchViewModel.searchGarbageWithPattern(pattern)
                filteredGarbage.observe(requireActivity(), Observer {
                    searchGarbageAdapter.submitList(it)
                })
                return true
            }
        })
    }
}

4.最后,如果不想让弹出的键盘挤压布局

修改Acticitymanifest文件
添加android:windowSoftInputMode="adjustNothing"
完整文件如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.gallery">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
        <activity android:name=".MainActivity"
            android:windowSoftInputMode="adjustNothing">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>
发布了107 篇原创文章 · 获赞 61 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/y_dd6011/article/details/104356108