29

I tried to get Search box to work on Action Bar Sherlock.

This is my PreLocationActivity:

    @ContentView(R.layout.search)
    public class PreLocationActivity extends RoboSherlockActivity {

        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //setContentView(R.layout.map_layout);
        } 

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            //Used to put dark icons on light action bar
             menu.add("Search")
             .setIcon(R.drawable.ic_search_inverse)
             .setActionView(R.layout.collapsible_edittext)
             .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
                return true;
        }

        @Override
        public boolean onSearchRequested() {
            return super.onSearchRequested();
        }
    }

This is my SearchableActivity:

@ContentView(R.layout.search)
public class SearchableActivity extends RoboSherlockFragmentActivity {

    @InjectView(R.id.addressListView) ListView addressView;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

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

    public void doGeoSearch(String query){
        Geocoder geocoder;
        ArrayList<Address> addresses;
        ArrayList<String> address = new ArrayList<String>() ;
        geocoder = new Geocoder(this, Locale.getDefault());
        try {
            addresses = (ArrayList<Address>) geocoder.getFromLocationName(query, 6);
            Log.d("Address",String.valueOf(addresses));
            for(int i = 0;i<addresses.size();i++)
            {
            String addr = new String();
            addr.concat(addresses.get(i).getAddressLine(0));
            addr.concat(addresses.get(i).getAddressLine(1));
            addr = addresses.get(i).getAddressLine(0) + addresses.get(i).getLocality() + addresses.get(i).getAdminArea();
            //addr.concat(addresses.get(i).getAddressLine(2));
            Log.d("addr",addr);
            address.add(addr);

            }

            SearchAddressAdapater addressList = new SearchAddressAdapater(getApplicationContext(),R.layout.search_list,addresses, SearchableActivity.this);
            addressView.setAdapter(addressList);
            //ListView addressListView = new ListView();
        } catch (IOException e) {
                //Handle exception
        }
    }

No success at all. As in, when I type something on the Prelocation Activity and press enter, nothing is being searched. Do I have to treat it as an EditText and write a text listener for that which then calls the geoCoder and gets me the locations or is there a smarter way to go about it?

jb.
  • 23,300
  • 18
  • 98
  • 136
Hick
  • 35,524
  • 46
  • 151
  • 243

3 Answers3

38

Android Support Library(v4 + v7):

Support Library v7: http://developer.android.com/tools/support-library/features.html#v7-appcompat

Google now supports the ActionBar compatibility back to Android 2.1(API 7).

It is easy to make the transition because the method names are the same and/or very similar.

Add the Support Library with Resources: http://developer.android.com/tools/support-library/setup.html#libs-with-res

Your Manifest: AndroidManifest.xml

<uses-sdk
  android:minSdkVersion="7"
  android:targetSdkVersion="17" />

Your Menu: menu.xml

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

ActionBarSherlock [deprecated, use appcompat]:

Here is how to use the standard SearchView and SearchManager in Android with ActionBarSherlock! I am using this code and works fine. I have tested this on Android 2.3(API 10) - Android 4.3(API 18).

Great Tutorial and Documentation:

http://developer.samsung.com/android/technical-docs/UI-unification-with-older-Android-versions-using-ActionBarSherlock

Keep in mind:

Custom Search with ActionBarSherlock(min. API 7)

SearchView with ActionBarSherlock(min. API 8)

Your Menu: menu.xml

<item
    android:id="@+id/menu_search"
    android:actionViewClass="com.actionbarsherlock.widget.SearchView"
    android:icon="@drawable/ic_action_search"
    android:showAsAction="ifRoom|collapseActionView"
    android:title="Search"/>

For Both:

Your Activity: MainActivity.java

public boolean onCreateOptionsMenu(Menu menu) 
{
        getSupportMenuInflater().inflate(R.menu.menu, menu);

        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
        if (null != searchView )
        {
            searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
            searchView.setIconifiedByDefault(false);   
        }

        SearchView.OnQueryTextListener queryTextListener = new SearchView.OnQueryTextListener() 
        {
            public boolean onQueryTextChange(String newText) 
            {
                // this is your adapter that will be filtered
                adapter.getFilter().filter(newText);
                return true;
            }

            public boolean onQueryTextSubmit(String query) 
            {
                // this is your adapter that will be filtered
                adapter.getFilter().filter(query);
                return true;
            }
        };
        searchView.setOnQueryTextListener(queryTextListener);
        
        return super.onCreateOptionsMenu(menu);
    }

Let me know if this works for you as well and let me know if you need anymore help!

Community
  • 1
  • 1
Jared Burrows
  • 54,294
  • 25
  • 151
  • 185
  • The adapter is your ListView adapter. Binds the data to the view. – Jared Burrows Apr 02 '13 at 19:23
  • ok... thanks. Just one more thing to ask, what if I need to include one more menuItem on the ActionBar, lets say a button. Generally, for multiple Items we use Switch case but here I am confused a little bit, that how can we create one more item on the Action Bar. – Sam-In-TechValens Apr 03 '13 at 05:38
  • This is strictly for the SearchView, you can use the Navigation List: http://stackoverflow.com/questions/8965609/how-to-expand-navigation-list-in-action-bar. – Jared Burrows Apr 03 '13 at 13:31
  • 1
    after including android:actionViewClass="com.actionbarsherlock.widget.SearchView" showing classcasteception . – user1526671 Apr 08 '13 at 06:15
  • Thats the right way to do it, using Action Bar Sherlock. Are you having trouble? – Jared Burrows Apr 09 '13 at 18:09
  • i follow this but i didn't get filtered listview. any suggstion – Pratik Butani May 07 '13 at 10:25
  • Can you please explain? I used this for an application. – Jared Burrows May 08 '13 at 01:40
  • Using a SherlockListFragment, and after some problems, the last line `return super.onCreateOptionsMenu(menu);` gives me an error. It needs as a second parameter a MenuInflater object, but I don't know where I get that. What I want to achieve is different menus in different fragments. – Deses May 09 '13 at 13:43
  • Just use the exact method I have: public boolean onCreateOptionsMenu(Menu menu) { return super.onCreateOptionsMenu(menu); } – Jared Burrows May 09 '13 at 14:58
  • @JaredBurrows I didn't get Filtered List – Pratik Butani May 13 '13 at 07:35
  • Adding your adapter filter adapter.getFilter().filter(newText); filters the text. If you have a custom adapter, you may have problems. – Jared Burrows May 13 '13 at 12:46
  • `@drawable/ic_action_search` gives a "No resource found" error for me. Might this have changed in the recent versions? (on the other hand, not specifying na icon gives a nice default search icon anyway). – Malabarba Aug 26 '13 at 10:27
  • @drawable is your drawable/ folder in your res/ folder. ic_action_search.png is apart of my images. – Jared Burrows Aug 26 '13 at 22:29
  • anybody worked on the Search Collapsible View on Actionbarcompat – LOG_TAG Oct 10 '13 at 11:28
  • Got the answer http://developer.android.com/reference/android/support/v7/widget/SearchView.html I'm migrating from ABS to ABC because of ABS bug 'ChildFragmentManager do not receive calls for OptionsMenus' – LOG_TAG Oct 10 '13 at 11:46
  • That is definitely the best solution because it is now supported by Google. – Jared Burrows Oct 10 '13 at 22:34
  • 1
    I downloaded ABS 4.4, extracted it, went to eclipse and created android project from source and selected actionbarsherlock, created a new project by referring your answer but i am getting an error Could not find class 'com.actionbarsherlock.widget.SuggestionsAdapter'. I also posted this as a question on stack overflow http://stackoverflow.com/q/20835518/992665 – Sar009 Dec 30 '13 at 09:09
  • 1
    @Sar009 Depending on the library, you need to make sure to use the correct themes as well. – Jared Burrows Dec 30 '13 at 18:50
  • I follow your whole procedure and I am getting the search View also in actionBar but when I am trying to search something, then it is not giving any result. Will you tell me the reason ? please. – Amit Jayaswal Jun 02 '14 at 05:54
26
private EditText search;

public boolean onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu)
{
    menu.add(0, 1, 1, R.string.menu_search).setIcon(R.drawable.ic_action_search).setActionView(R.layout.action_search).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(com.actionbarsherlock.view.MenuItem item)
{
    switch (item.getItemId())
    {
        case 1:
        search = (EditText) item.getActionView();
        search.addTextChangedListener(filterTextWatcher);
        search.requestFocus();
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
    }
}

private TextWatcher filterTextWatcher = new TextWatcher()
{
    public void afterTextChanged(Editable s)
    {
    }

    public void beforeTextChanged(CharSequence s, int start, int count, int after)
    {
    }

    public void onTextChanged(CharSequence s, int start, int before, int count)
    {
        // your search logic here
    }
};
Jared Burrows
  • 54,294
  • 25
  • 151
  • 185
Georgy Gobozov
  • 13,633
  • 8
  • 72
  • 78
3

A similar question there are here where I had the problem to assign the adapter.

How to implement search widget with a listview using SherlockActionbar?

I hope that it would help because I had the same problem.

To use the adapter the best way is that the class implements SearchView.OnQueryTextListener and then you don´t have to create the inner class and you will have the adapter.

In your code will be something as:

public class MainActivity extends SherlockListActivity implements SearchView.OnQueryTextListener

and then in the class you have to define the methods. The adapter will be the adapter that you have in your class ArrayAdapter adapter. But you should define it as private in the class.

public boolean onQueryTextChange(String newText) {
    // this is your adapter that will be filtered
    adapter.getFilter().filter(newText);
    return true;
}

public boolean onQueryTextSubmit(String query) {
    // this is your adapter that will be filtered
    adapter.getFilter().filter(query);
    return true;
}

In the line where you are setting:

 searchView.setOnQueryTextListener(queryTextListener);

Should be:

 searchView.setOnQueryTextListener(this);

If you have any problem let me know, I was with a similar problem today and read your question without answer.

Community
  • 1
  • 1
Javier Salinas
  • 617
  • 6
  • 15