Now you can Subscribe using RSS

Submit your Email

Monday

Properly using searchView widget with AppCompat | Android Beginners

Vishal Shrestha
In this article we will learn using the searchView widget using V7 support library and resolving the most common errors while using the searchView widget.
Most common and confusing error that I think people face is-

1.NullPointer Error in searchView

We will get into it later but first let us look at the things we need in order to get a search widget working.
1. We need an activity to have the search widget.
2. A searchable activity.
3. Search configuration
4. Manifest meta and intent

This all may seem a little complex but let's begin and it will all make sense and come together.
Here is what our final result will look like-

Android SearchView Widget ActionBar
SearchView Widget in ActionBar

SearchView Widget Expanded for Input
First create a menu in res/menu folder with searchView item to be shown in Toolbar(Action bar). Name the menu menu.xml.

Code in menu.xml

<menu 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"
    tools:context=".MainActivity">
    <item android:id="@+id/action_search" android:title="Search"
        android:icon="@drawable/ic_action_search"
        app:actionViewClass="android.support.v7.widget.SearchView" app:showAsAction="ifRoom"/>
</menu>
 
If you want to show the searchView icon permanently then you can set app:showAsAction="Always". If you set this to ifRoom, then it will be available only when there is room on the toolbar or else it will be available if you click on the options icon(Three vertical dots).
This is the one part that causes most errors while using searchView Widget-
Don't forget to add app:actionViewClass="android.support.v7.widget.SearchView" if you want to support earlier versions also. Or else if you are developing for android 3.0 or above you can write actionViewClass="android .widget.searchview.

Now we will make an activity in which the toolbar will hold searchView widget. This if fairly simple, just create the activity and inflate our menu. Remember this is not our searchable Activity. This activity just holds the searchView widget. We take the query that user enters in this activity and pass it to another activity that processes it. That another activity is our searchable activity. Code in MainActivity.java- Inflate the menu in onOptionCreateMenu like this-

public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
 
This will inflate the menu and our action view should be visible in the toolbar now. But it will not do anything it will just be visible. To make it respond to touch and expand for data in put we need to put more lines. The lines after inflating, the overall code in onCreateOptionsMenu is-

public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
 
        // Get the SearchView and set the searchableview configuration
        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        MenuItem searchItem = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
        searchView.setSearchableInfo(searchManager.getSearchableInfo(new ComponentName(this, SearchableActivity.class)));

        return true;
    }
 
 NOTE- We are using support library that's why we used menu.findItem. If you are not using support library then you can directly use menu.
This is the another part that causes most errors while using searchView Widget-
Remember that we are sending our search query to another activity which will handle it, that's why we used, new ComponentName(this, SearchableActivity.class as parameter for searchView.setSearchableInfo. This is how we will usually use the searchView. But if you want to use your current activity as searchable activity then you should pass getComponentName() as parameter. Notice SearchableActivity.class, this is the class we will be creating to receive and handle user search query. We have created an activity with the searchView but if you test it now, your app will throw an error because we have not created Searchable Activity, Search Configuration and We have not edited manifest.xml to accommodate search activity. Let's do that now. We just receive the query in searchable activity and handle it anyway you want. Code in SearchableActivity.java-

public void onCreate(Bundle savedInstanceState) {
         ...//Your usual code
        handleIntent(getIntent());
    }
    @Override

    protected void onNewIntent(Intent intent) {
        ...
        handleIntent(intent);
    }

    private void handleIntent(Intent intent) { 
         if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
            String query = intent.getStringExtra(SearchManager.QUERY);
            //use the query to search your data somehow
        }
    }
 
Simple Right? Good going, now most of the job is done, now we just need to create a searchable configuration and modify manifest. Searchable configuration defines how the SearchView behaves. Create searchable.xml in res/xml folder. Your searchable configuration must have android:label attribute. It's value must be same as android:label of <application> or <activity> element of Manifest. If you want to give user a hint of what to enter in the searchBox you can add android:hint label. Code in searchable.xml-

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
        android:label="@string/app_name"
        android:hint="Search any food Item" />
 
We are almost done, just need to modify the manifest.xml file- We need to add meta data for both our MainActivity and SearchableActivity- In MainActivity's meta date we need to define which activity is our searchable activity. and In or searchableActivity's meta data we point to searchable configuration resource. Code in manifest.xml-

<activity
            android:name=".MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data android:name="android.app.default_searchable"
                android:value=".SearchableActivity" />
        </activity>
 
         <activity
            android:name=".SearchableActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.SEARCH" />
            </intent-filter>
            <meta-data
                android:name="android.app.searchable"
                android:resource="@xml/searchable" />
        </activity>
 
That's it we are done! One thing, you must have noticed I didn't show Layout code's for any of the activity, It' s not necessary, SearchView widget is added programmatically and you can create any type of layout you want. Run it test it! Search for anything, food or stuff. Boy I am hungry. And Yeah, don't forget to ask anything you want! Cheers

 Know the Difference Between using Bundle and PutExtra?
 StartActivity for result or StartActivty?

Vishal Shrestha / Author & Founder

A developer by profession, a born Adventurer. I mainly do Android but like to get my hands dirty with web development and a little bit of Python. I would't rather go on a Trek than a party and you can find me having a few rounds with the heavy bag to let out the steam ;)

For Business info : My Portfolio Site.

2 comments:

Coprights @ 2017 | The Code City by Vishal Shrestha Vishal Shrestha