Android SearchView Widget With List Item as a Result

5.9k views Asked by At

anyone can give me a solution on how to use searchView widget(not in action bar) to show a list of result base on what the user type in searchView.
i am very new in developing android application and it happen that i want to try to create a simple application that can retrieve a data from the database.
i try to search from the internet and i found 'searchView' which i am able to search a data.
i copy the code from the internet and modify some part. i read the code, i actually understand some code but not all, now from the MainActivity, i see that the 'onSearchRequested();' is called and then an intent is start with a searchView in action bar.
i try to modify the code with putting a searchView widget at the layout, i want to use this instead of 'onSearchRequested();' but im stock, dont know how show the 'ListView' as the result.

this what the run looks like:
a searchview in actionbar
enter image description here

and i want to change it like:
a searchView with result of list item but not in action bar
enter image description here

the code::

'MainActivity.java' // The original

public class MainActivity extends FragmentActivity{

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

        Button btn = (Button) findViewById(R.id.btn_search);    
        btn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {           
                onSearchRequested();    // This will start eveything on button click            
            }
        });
    }
}

'MainActivity.java' // I already Modify

public class MainActivity extends FragmentActivity{

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

        Button btn = (Button) findViewById(R.id.btn_search);    
        btn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {           
                onSearchRequested();                
            }
        });


        SearchView searchView = (SearchView)findViewById(R.id.searchView1);

        //This is just some code trying to customize the SearchView 
        searchView.setQueryHint("Type Word...");
        int searchPlateId = searchView.getContext().getResources().getIdentifier("android:id/search_plate", null, null);
        View searchPlate = searchView.findViewById(searchPlateId);
        if (searchPlate!=null) {
            searchPlate.setBackgroundColor(Color.WHITE);
            int searchTextId = searchPlate.getContext().getResources().getIdentifier("android:id/search_src_text", null, null);
            TextView searchText = (TextView) searchPlate.findViewById(searchTextId);
            if (searchText!=null) {
                searchText.setTextColor(Color.DKGRAY);
                searchText.setHintTextColor(Color.LTGRAY);

            }
        }

        // and im stock here, dont now what next to do

    }
}

SearchableActivity.java //Nothings modify here

public class SearchableActivity extends FragmentActivity implements LoaderCallbacks<Cursor> {

    ListView mLVCountries;
    SimpleCursorAdapter mCursorAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_searchable);
        // Getting reference to Country List
        mLVCountries = (ListView)findViewById(R.id.lv_countries);       
        // Setting item click listener      
        mLVCountries.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Intent countryIntent = new Intent(getApplicationContext(), CountryActivity.class);
                // Creating a uri to fetch country details corresponding to selected listview item
                Uri data = Uri.withAppendedPath(CountryContentProvider.CONTENT_URI, String.valueOf(id));
                // Setting uri to the data on the intent
                countryIntent.setData(data);
                // Open the activity
                startActivity(countryIntent);
            }
        });
        // Defining CursorAdapter for the ListView      
        mCursorAdapter = new SimpleCursorAdapter(getBaseContext(),
                android.R.layout.simple_list_item_1,
                null,
                new String[] { SearchManager.SUGGEST_COLUMN_TEXT_1},
                new int[] { android.R.id.text1}, 0);
        // Setting the cursor adapter for the country listview
        mLVCountries.setAdapter(mCursorAdapter);
        // Getting the intent that invoked this activity
        Intent intent = getIntent();        
        // If this activity is invoked by selecting an item from Suggestion of Search dialog or 
        // from listview of SearchActivity
        if(intent.getAction().equals(Intent.ACTION_VIEW)){ 
            Intent countryIntent = new Intent(this, CountryActivity.class);
            countryIntent.setData(intent.getData());
            startActivity(countryIntent);
            finish();           
        }else if(intent.getAction().equals(Intent.ACTION_SEARCH)){ // If this activity is invoked, when user presses "Go" in the Keyboard of Search Dialog
            String query = intent.getStringExtra(SearchManager.QUERY);
            doSearch(query);
        }       
    }   
    private void doSearch(String query){
        Bundle data = new Bundle();
        data.putString("query", query);
        // Invoking onCreateLoader() in non-ui thread
        getSupportLoaderManager().initLoader(1, data, this);        
    }
    /** This method is invoked by initLoader() */
    @Override
    public Loader<Cursor> onCreateLoader(int arg0, Bundle data) {
        Uri uri = CountryContentProvider.CONTENT_URI;       
        return new CursorLoader(getBaseContext(), uri, null, null , new String[]{data.getString("query")}, null);   
    }
    /** This method is executed in ui thread, after onCreateLoader() */
    @Override
    public void onLoadFinished(Loader<Cursor> arg0, Cursor c) { 
        mCursorAdapter.swapCursor(c);       
    }
    @Override
    public void onLoaderReset(Loader<Cursor> arg0) {
        // TODO Auto-generated method stub      
    }       
}

activity_searchable.xml
//This is the list item result i want to show this under the searchView as the result

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/lv_countries"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />    
</LinearLayout>

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="@string/search_hint"
    android:searchSettingsDescription="@string/search_settings"

    android:searchSuggestAuthority="in.wptrafficanalyzer.searchdialogdemo.CountryContentProvider"
    android:searchSuggestIntentAction="android.intent.action.VIEW"
    android:searchSuggestIntentData="content://in.wptrafficanalyzer.searchdialogdemo.CountryContentProvider/countries"
    android:searchSuggestSelection=" ?"
    android:searchSuggestThreshold="1"    

    android:includeInGlobalSearch="true" >
</searchable>

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"    
    tools:context=".MainActivity" >

    <SearchView
        android:id="@+id/searchView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:iconifiedByDefault="false"
        android:imeOptions="actionSearch" >

    </SearchView>

    <Button
        android:id="@+id/btn_search"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/searchView1"
        android:text="@string/search" />

</RelativeLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="in.wptrafficanalyzer.searchdialogdemo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="11"
        android:targetSdkVersion="21" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <!--  Activity with SearchDialog enabled -->
        <activity
            android:name="in.wptrafficanalyzer.searchdialogdemo.MainActivity"
            android:label="@string/app_name" >            
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <!-- Enabling Search Dialog -->                      
            <meta-data 
                android:name="android.app.default_searchable"
                android:value=".SearchableActivity" />                        
        </activity>

        <!-- A Searchable activity, that handles the searches -->
        <activity 
            android:name=".SearchableActivity" >            
            <intent-filter>
                <action android:name="android.intent.action.SEARCH" />
            </intent-filter>
            <meta-data 
                android:name="android.app.searchable"
                android:resource="@xml/searchable"/>            
        </activity>
        <!--  Activity that shows the country details -->
        <activity android:name=".CountryActivity" />
        <!-- Content Provider to query sqlite database -->
        <provider 
            android:name=".CountryContentProvider"  
            android:authorities="in.wptrafficanalyzer.searchdialogdemo.CountryContentProvider"
            android:exported="true" />        
    </application>

</manifest>

Again, Please im just a newbie, if there's something wrong on my question im really sorry, i love programming and im just trying to learn. anyway, thank you very much!!! any help will be appreciated!

2

There are 2 answers

1
Polar On BEST ANSWER

Did not understand the whole question, but maybe you want to forget the onSearchRequested(); and change it with your customize searchView. try this,

you dont need to change anything on your code except in MainActivity. if you don't want onSearchRequested(); for some reason... here..

If you have a custom searchView in your actionbar and use it instead of searchView in your layout you may use this code:

public class MainActivity extends FragmentActivity{
    static SearchView searchView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main, menu);

        //Your design here
        MenuItem menuItem = menu.findItem(R.id.search);
        SearchView searchView = (SearchView) menuItem.getActionView();
        searchView.setIconifiedByDefault(false);
        searchView.setQueryHint("Type something...");
        int searchPlateId = searchView.getContext().getResources().getIdentifier("android:id/search_plate", null, null);
        View searchPlate = searchView.findViewById(searchPlateId);
        if (searchPlate!=null) {
            searchPlate.setBackgroundColor(Color.DKGRAY);
            int searchTextId = searchPlate.getContext().getResources().getIdentifier("android:id/search_src_text", null, null);
            TextView searchText = (TextView) searchPlate.findViewById(searchTextId);
            if (searchText!=null) {
                searchText.setTextColor(Color.WHITE);
                searchText.setHintTextColor(Color.WHITE);
            }
        }

      //Maybe this is what you want
     // Associate searchable configuration with the SearchView
        SearchManager searchManager =
               (SearchManager) getSystemService(Context.SEARCH_SERVICE);
       searchView = (SearchView) menu.findItem(R.id.search).getActionView();
        searchView.setSearchableInfo(
                searchManager.getSearchableInfo(getComponentName()));

        return true;
    }
}

and in you res/menu/main.xml add this

<item android:id="@+id/search"
   android:title="@string/search_title"
   android:icon="@drawable/ic_search"
   android:showAsAction="collapseActionView|ifRoom"
   android:actionViewClass="android.widget.SearchView" />

and try to execute your project

or if you really want to use your custom searchView in your layout then this:

public class MainActivity extends FragmentActivity{
    static SearchView searchView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        searchView = (SearchView)findViewById(R.id.searchView1);
        searchView.setQueryHint("Type Word...");
        int searchPlateId = searchView.getContext().getResources().getIdentifier("android:id/search_plate", null, null);
        View searchPlate = searchView.findViewById(searchPlateId);
        if (searchPlate!=null) {
            searchPlate.setBackgroundColor(Color.WHITE);
            int searchTextId = searchPlate.getContext().getResources().getIdentifier("android:id/search_src_text", null, null);
            TextView searchText = (TextView) searchPlate.findViewById(searchTextId);
            if (searchText!=null) {
                searchText.setTextColor(Color.DKGRAY);
                searchText.setHintTextColor(Color.LTGRAY);

                //This is what you want?
                SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
                searchView.getRootView();//Notice that i change this
                searchView.setSearchableInfo(
                searchManager.getSearchableInfo(getComponentName()));
            }
        }       
}

reference:: Setting Up the Search...

8
Moinkhan On

Just refer this link ..

http://wptrafficanalyzer.in/blog/customizing-autocompletetextview-to-display-images-and-text-in-the-suggestion-list-using-simpleadapter-in-android/

It's not a big deal. If You know the CustomListView then it's easy for you.