Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I add a searchview to my Android app?

Tags:

android

search

I want to add a searchview to my Android app but I can't understand the documentation. I have added

<searchable xmlns:android="http://schemas.android.com/apk/res/android"
       android:includeInGlobalSearch="true"
       android:searchSuggestAuthority="dictionary"
       android:searchSuggestIntentAction="android.intent.action.VIEW">
</searchable>

to my xml and <intent-filter>

<action android:name="android.intent.action.SEARCH" />
<category android:name="android.intent.category.DEFAULT" /
</intent-filter>
<meta-data android:name="android.app.searchable" android:resource="@xml/searchable" />

to my manifest. But where should the provider-tag go? i get a error inflating class exception when running the app. Anyone know of a good tutorial? THanks!

like image 949
kakka47 Avatar asked Feb 24 '23 00:02

kakka47


1 Answers

This answer is quite later, but as I can see, other answers are only answer-links. Then, I will try to provide some explainations with short example code.
Adding a SearchView is described in the Documentation, and it's quite easy to follow the steps. As we can read on Create a Search Interface topic:

The<intent-filter>does not need a<category>with the DEFAULT value (which you usually see in<activity>elements), because the system delivers the ACTION_SEARCH intent explicitly to your searchable activity, using its component name.

Then, your manifest become:

<intent-filter>
    <action android:name="android.intent.action.SEARCH" />
</intent-filter>  
<meta-data android:name="android.app.searchable"
    android:resource="@xml/my_searchable_layout"/>

"Traditionally, your search results should be presented in a ListView, so you might want your searchable activity to extend ListActivity" - still from Docs. So your SearchActivity might be:

public class SearchActivity extends ListActivity { }  

"When the user executes a search from the search dialog or a search widget, the system creates an Intent and stores the user query in it. The system then starts the activity that you've declared to handle searches (the "searchable activity") and delivers it the intent". You need to get the query search from the search dialog or widget by using an Intent in onCreate method:

// Get the intent, verify the action and get the query
Intent intent = getIntent();
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
    // Receive the query
    String query = intent.getStringExtra(SearchManager.QUERY);
    // Search method..
    doMySearch(query);
}  

doMySearch() can be an AsyncTask, a new Thread.. connected to a SQLite DataBase, a SharedPreference, whatever.. "The process of storing and searching your data is unique to your application". This being said, you should create an Adapter to provide your results in the list.

Here is a short ListActivity example for SearchActivity using an asynctask to populate a list:

public class SearchActivity extends ListActivity {
    // Create an array
    String[] values;

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

        Intent intent = getIntent();
        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
            String query = intent.getStringExtra(SearchManager.QUERY);
            // At the end of doMySearch(), you can populate 
            // a String Array as resultStringArray[] and set the Adapter
            doMySearch(query);
        }
    }

    class doMySearch extends AsyncTask<String,Void,String> {
        @Override
        protected String doInBackground(String... params) {
            // Connect to a SQLite DataBase, do some stuff..
            // Populate the Array, and return a succeed message
            // As String succeed = "Loaded";
            return succeed;
        }
        @Override
        protected void onPostExecute(String result) {
            if(result.equals("Loaded") {
                 // You can create and populate an Adapter
                 ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                            SearchActivity.this,
                            android.R.layout.simple_list_item_1, values);
                 setListAdapter(adapter);
            }
        }
    }
}  

Finally, I prefer to use a SearchView widget with the AppCompat or ActionBarSherlock and it describes at the end of the topic. It's I think more adapted since you asked your question (3 years ago ^^). So, to do:

// Example with AppCompat
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the options menu
    getMenuInflater().inflate(R.menu.options_menu, menu);
    MenuItem searchItem = menu.findItem(R.id.menu_search);
    // Get the SearchView and set the searchable configuration
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
    // Assumes current activity is the searchable activity
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setIconifiedByDefault(true); // Iconify the widget
    return true;
}  

And perform a startActivity() method to pass the query to SearchActivity in onOptionsItemSelected method. Then, you will just to add this search item into your menu as follows (don't forget the custom prefix) like you can see on Adding an Action View:

<item android:id="@+id/action_search"
    android:title="@string/action_search"
    android:icon="@drawable/ic_action_search"
    yourapp:showAsAction="ifRoom|collapseActionView"
    yourapp:actionViewClass="android.support.v7.widget.SearchView" />

In sample Docs, you have the Searchable Dictionary demo which contains a ListView and provide a full demo of connecting SQLite DataBase via an Adapter.
Voila! I hope you found the solution yet and this post will help someone which want the same.

like image 85
Blo Avatar answered Feb 28 '23 19:02

Blo