androidkotlinsearchviewmaterial-components-android

How to setup Material Search bar in Android


I'm trying to implement a Material SearchBar in my Android app. This should actually have a button on the left, which extends the left navigation layout (the code for the NavLayout is already available and functional) and a search field to filter something with an onTextChange listener.

I am thinking of a design similar to Gmail or the Material page example (particularly with the Button location)

enter image description here

On The Material3 Website you can see that it is possible to have a design with a Button on the left, which could be used to open a NavigationDrawer and a Button on the right to open a Account Page or something similar

(link: https://m3.material.io/components/search/specs#0eca344e-55ba-4a57-9c15-18eb1591ea53) ->Here its called (1) Search Bar configuration with Avatar

But how can I apply such a theme with this functionality?

My Code:

search_menu.xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_search"
        android:icon="@drawable/mail"
        android:title="Search"
        app:showAsAction="collapseActionView|ifRoom"/>
</menu>

activity_main.xml: Within a constraint Layout

<com.google.android.material.appbar.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <com.google.android.material.search.SearchBar
                android:id="@+id/search_bar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:forceDefaultNavigationOnClickListener="false"
                android:hint="hallo" />
        </com.google.android.material.appbar.AppBarLayout>

MainActivity.kt:

lateinit var searchBar: SearchBar
lateinit var searchView: SearchBar

override fun onCreate(savedInstanceState: Bundle?) {
        searchBar = findViewById(R.id.search_bar)
        searchView = findViewById(R.id.searchView)
        searchBar.inflateMenu(R.menu.search_menu)
        searchView.setupWithSearchBar(searchBar)
        searchBar.setOnMenuItemClickListener { item ->
            if(item.itemId == R.id.action_search){
                drawerLayout.openDrawer(GravityCompat.START)
            }
            true
        }
}

Solution

  • To set up like example in the document about SearchBar and Navigation Drawer ( Material Design 3 )

    Structure of .xml should be

    <DrawerLayout>
       <CoordinatorLayout>
           <AppBarLayout> 
               <SearchBar/>
           </AppBarLayout> 
               <SearchView>
               </SearchView>
       </CoordinatorLayout>
          <NavigationView/>
    </DrawerLayout>
    

    About the code activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.drawerlayout.widget.DrawerLayout 
        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/drawerLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">
    
        <androidx.coordinatorlayout.widget.CoordinatorLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true">
    
            <com.google.android.material.appbar.AppBarLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:fitsSystemWindows="true"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent">
    
                <com.google.android.material.search.SearchBar
                    android:id="@+id/search_bar"
                    style="@style/Widget.Material3.SearchBar"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="hallo"
        // IMPORTANT CODE // app:forceDefaultNavigationOnClickListener="false"
        // IMPORTANT CODE // app:navigationIcon="@drawable/ic_menu" />
    
            </com.google.android.material.appbar.AppBarLayout>
    
            <com.google.android.material.search.SearchView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:hint="Search something"
                app:layout_anchor="@id/search_bar">
    
            </com.google.android.material.search.SearchView>
    
        </androidx.coordinatorlayout.widget.CoordinatorLayout>
    
        <com.google.android.material.navigation.NavigationView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            app:headerLayout="@layout/header_navigation_drawer"
            app:menu="@menu/nav_drawer_menu" />
    
    </androidx.drawerlayout.widget.DrawerLayout>
    

    In MainActivity set up like this

    val drawerLayout = findViewById<DrawerLayout>(R.id.drawerLayout)
    val searchBar = findViewById<SearchBar>(R.id.search_bar)
    searchBar.setNavigationOnClickListener { drawerLayout.open() }  // IMPORTANT CODE //
    
    // To listen click on item menu on the right of SearchBar you need to set up like this
    searchBar.inflateMenu(R.menu.<Your menu search bar>)
    searchBar.setOnMenuItemClickListener {
            when (it.itemId) {
                R.id.test1-> {}
                R.id.test2-> {}
            }
            true
        }
    

    Video Result

    enter image description here

    Comment if you get problem with this