菜單欄中和頁面上的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>
發佈了92 篇原創文章 · 獲贊 40 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章