web-dev-qa-db-fra.com

Comment implémenter un widget de recherche dans Action Bar Sherlock?

J'ai essayé de faire fonctionner la zone de recherche sur Action Bar Sherlock.

Voici mon 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();
        }
    }

Voici mon 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
        }
    }

Pas de succès du tout. Comme dans, lorsque je tape quelque chose sur l'activité de prélocation et que j'appuie sur Entrée, rien n'est recherché. Dois-je le traiter comme un EditText et écrire un écouteur de texte pour celui qui appelle ensuite le geoCoder et me donne les emplacements ou existe-t-il une façon plus intelligente de procéder?

29
Hick
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
    }
};
26
Georgy Gobozov

Bibliothèque de support Android (v4 + v7):

Bibliothèque de support v7: http://developer.Android.com/tools/support-library/features.html#v7-appcompat

Google prend désormais en charge la compatibilité ActionBar vers Android 2.1 (API 7).

La transition est facile car les noms de méthode sont identiques et/ou très similaires.

Ajoutez la bibliothèque de support avec des ressources: http://developer.Android.com/tools/support-library/setup.html#libs -avec-res

Votre manifeste: AndroidManifest.xml

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

Votre 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 [obsolète, utilisez appcompat]:

Voici comment utiliser le SearchView et le SearchManager standard dans Android avec ActionBarSherlock! J'utilise ce code et fonctionne très bien. Je l'ai testé sur Android 2.3 ( API 10) - Android 4.3 (API 18).

Grand tutoriel et documentation:

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

Gardez à l'esprit:

Recherche personnalisée avec ActionBarSherlock (min. API 7)

SearchView avec ActionBarSherlock (min. API 8)

Votre 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"/>

Pour les deux:

Votre activité: 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);
    }

Faites-moi savoir si cela fonctionne aussi pour vous et faites-moi savoir si vous avez besoin d'aide!

38
Jared Burrows

Une question similaire il y a ici où j'ai eu le problème pour affecter l'adaptateur.

Comment implémenter un widget de recherche avec une vue de liste en utilisant SherlockActionbar?

J'espère que cela aiderait car j'avais le même problème.

Pour utiliser l'adaptateur, la meilleure façon est que la classe implémente SearchView.OnQueryTextListener et que vous n'ayez pas à créer la classe interne et vous aurez l'adaptateur.

Dans votre code sera quelque chose comme:

public class MainActivity extends SherlockListActivity implements SearchView.OnQueryTextListener

puis dans la classe, vous devez définir les méthodes. L'adaptateur sera l'adaptateur que vous avez dans votre adaptateur ArrayAdapter de classe. Mais vous devez le définir comme privé dans la classe.

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;
}

Dans la ligne où vous définissez:

 searchView.setOnQueryTextListener(queryTextListener);

Devrait être:

 searchView.setOnQueryTextListener(this);

Si vous avez un problème, faites-le moi savoir, j'étais avec un problème similaire aujourd'hui et lisez votre question sans réponse.

3
Javier Salinas