How to Search an Item in ListView using EditText and TextWatcher in Android?
Some applications provide a search bar for looking up any particular item from a list of items. Technically, a search bar is an EditText and an item list can be a ListView, RecyclerView, or a GridView that contains some items. Now, when a user types something in the EditText, the list must update in accordance with the text that the user types. String matching algorithms are used to check if the typed text is a substring of any of the list items, and if any, then those items are displayed in the updates ListView. However, creating a separate function or an algorithm to perform this search operation consumes more lines on the editor. To this, one can make use of a TextWatcher object, a public interface, which implements on the EditText and checks if the text changes. So in this article, we will show you how you could implement a TextWatcher on an EditText to update the resultant ListView when input is given by the user. Follow the below steps once the IDE is ready.
Step by Step Implementation
Step 1: Create a New Project in Android Studio
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. We demonstrated the application in Kotlin, so make sure you select Kotlin as the primary language while creating a New Project.
Step 2: Working with the activity_main.xml file
Navigate to the app > res > layout > activity_main.xml and add the below code to that file. Below is the code for the activity_main.xml file. Create an EditText on the top of the activity which shall be the assumed search bar and a ListView below it for displaying the items.
XML
<? xml version = "1.0" encoding = "utf-8" ?> < RelativeLayout android:layout_width = "match_parent" android:layout_height = "match_parent" tools:context = ".MainActivity" > < EditText android:id = "@+id/edit_text" android:layout_width = "match_parent" android:layout_height = "50sp" android:inputType = "text" /> < ListView android:id = "@+id/list_view" android:layout_below = "@id/edit_text" android:layout_width = "match_parent" android:layout_height = "match_parent" /> </ RelativeLayout > |
Step 3: Working with the MainActivity.kt file
Go to the MainActivity.kt file and refer to the following code. Below is the code for the MainActivity.kt file. We declared an array of items as shown in the code. These items are initially displayed in the ListView with the use of an adapter. Next, the TextWatcher is implemented on the EditText. TextWatcher implements three member functions, i.e., beforeTextChanger(), onTextChanged(), and afterTextChanged(). We are concerned with onTextChanged() as we want to update the ListView when the text changes in real-time. This function takes in the entire string from the EditText, filters the adapter for array elements based on the input and the updated ListView is displayed. Comments are added inside the code to understand the code in more detail.
Kotlin
import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.text.Editable import android.text.TextWatcher import android.widget.ArrayAdapter import android.widget.EditText import android.widget.ListView class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super .onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Declare and Initialize the EditText // and ListView from the layout file. val mSearch = findViewById<EditText>(R.id.edit_text) val mListView = findViewById<ListView>(R.id.list_view) // Declare array of elements, create an adapter // and display the array in the ListView val mCities = arrayOf( "Mumbai" , "Mohali" , "Delhi" , "Dehradun" , "Darjeeling" , "Bengaluru" ) val mArrayAdapter = ArrayAdapter( this , android.R.layout.simple_list_item_1, android.R.id.text1, mCities) mListView.adapter = mArrayAdapter // TextWatcher to check if the EditText text changes mSearch.addTextChangedListener(object: TextWatcher{ override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { // Do Nothing } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { mArrayAdapter.filter.filter(s) } override fun afterTextChanged(s: Editable?) { // Do Nothing } }) } } |
Output:
We can see that the ListView is updated based on the input given.
Please Login to comment...