Open In App

Material Search Bar in Android

Last Updated : 18 Feb, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

A Material Search Bar is an essential component in modern Android applications, enhancing the user experience by allowing quick searches. Google’s Material Design provides sleek, user-friendly search bars that blend well with UI/UX standards. This guide will help you integrate a Material Search Bar in your Android app.

Material-Search-Bar-in-Android-2

Anatomy of the Material Search Bar

In the below anatomy taking the example of an basic application, one can see the primary action here is search and on tap it opens the Search View.

Material-Search-Bar-in-Android-3


Steps for Creating Search Bar

Step 1: Create a new Android Studio project

To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio.

Step 2: Adding the dependency to the build.gradle(:app) file

We will be using Android’s Material Design Library so we need to import it in the build.gradle.kts (Module :app) file Here’s the dependency we need to add:

implementation("com.google.android.material:material:1.12.0")

Step 3: Working with activity_main.xml file

We are going to create a SearchBar and a SearchView, which work together to let users type in their search. There is also a ListView that shows a list of names. When the user taps on the SearchBar, the SearchView pops up so they can type in a name to search. The whole layout is inside an AppBarLayout to make sure everything looks neat and follows Material Design rules.

activity_main.xml:

XML
<androidx.coordinatorlayout.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <ListView
            android:id="@+id/listView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </LinearLayout>

    <com.google.android.material.search.SearchView
        android:id="@+id/search_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:hint="Search name"
        app:layout_anchor="@id/search_bar"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Layout Design:

Layout



Step : Working with the MainActivity file

First, let's set up the SearchBar, SearchView, and ListView with a list of names. When the user taps on the SearchBar, the SearchView appears so they can start searching. As they type, a TextWatcher listens for changes and updates the list to only show names that match the search. This way, the list filters in real-time, making it easy for users to find what they are looking for. The code for the MainActivity file is given below in both Java and Kotlin.

MainActivity.java
package org.geeksforgeeks.demo;

import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.google.android.material.search.SearchBar;
import com.google.android.material.search.SearchView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private SearchView searchView;
    private SearchBar searchBar;
    private ListView listView;
    private ArrayAdapter<String> adapter;
    
    private final List<String> dataList = Arrays.asList("Alice", "Bob", "Charlie", "David", "Eve", "Frank");
    private final List<String> filteredList = new ArrayList<>();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        searchView = findViewById(R.id.search_view);
        searchBar = findViewById(R.id.search_bar);
        listView = findViewById(R.id.listView);

        // Hide search on submit and carry the text to search bar
        searchView.getEditText().setOnEditorActionListener((v, actionId, event) -> {
            searchBar.setText(searchView.getText().toString());
            searchView.hide();
            return false;
        });

        // Initialize ListView with data
        filteredList.addAll(dataList);
        adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, filteredList);
        listView.setAdapter(adapter);

        // Show searchView when searchBar is clicked
        searchBar.setOnClickListener(v -> searchView.show());

        // Handle text change in SearchView input
        searchView.getEditText().addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                filterList(s.toString());
            }

            @Override
            public void afterTextChanged(Editable s) {}
        });
    }

    private void filterList(String query) {
        filteredList.clear();
        if (query == null || query.isEmpty()) {
            filteredList.addAll(dataList);
        } else {
            for (String item : dataList) {
                if (item.toLowerCase().contains(query.toLowerCase())) {
                    filteredList.add(item);
                }
            }
        }
        adapter.notifyDataSetChanged();
    }
}
MainActivity.kt
package org.geeksforgeeks.demo

import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.widget.ArrayAdapter
import android.widget.ListView
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.search.SearchBar
import com.google.android.material.search.SearchView

class MainActivity : AppCompatActivity() {
    private lateinit var searchView: SearchView
    private lateinit var searchBar: SearchBar
    private lateinit var listView: ListView
    private lateinit var adapter: ArrayAdapter<String>
    private val dataList = listOf("Alice", "Bob", "Charlie", "David", "Eve", "Frank")
    private val filteredList = mutableListOf<String>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        searchView = findViewById(R.id.search_view)
        searchBar = findViewById(R.id.search_bar)
        listView = findViewById(R.id.listView)

        // Hide search on submit and carry the text to search bar
        searchView.editText
            .setOnEditorActionListener { _, _, _ ->
                searchBar.setText(searchView.text)
                searchView.hide()
                false
            }

        // Initialize ListView with data
        filteredList.addAll(dataList)
        adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, filteredList)
        listView.adapter = adapter

        // Show searchView when searchBar is clicked
        searchBar.setOnClickListener {
            searchView.show()
        }

        // Handle text change in SearchView input
        searchView.editText.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                filterList(s.toString())
            }

            override fun afterTextChanged(s: Editable?) {}
        })
    }

    private fun filterList(query: String?) {
        filteredList.clear()
        if (query.isNullOrEmpty()) {
            filteredList.addAll(dataList)
        } else {
            filteredList.addAll(dataList.filter { it.contains(query, ignoreCase = true) })
        }
        adapter.notifyDataSetChanged()
    }
}

Output:


Next Article

Similar Reads