web-dev-qa-db-fra.com

Android Action Bar SearchView as Autocomplete?

J'utilise un SearchView dans la barre d'actions. Je souhaite utiliser la fonction de saisie semi-automatique sur la vue de recherche pour obtenir les résultats de la base de données.

Est-ce possible? Ou dois-je utiliser une zone de texte personnalisée, puis ajouter la saisie semi-automatique à cela?

38
Harsha M V

J'ai utilisé AutoCompleteTextView personnalisé et je l'ai ajouté dans ActionBar.

enter image description here

public class MainActivity extends Activity {

    private static final String[] COUNTRIES = new String[] { "Belgium",
            "France", "France_", "Italy", "Germany", "Spain" };

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

        ActionBar actionBar = getActionBar();
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setDisplayShowCustomEnabled(true);
        // actionBar.setDisplayShowTitleEnabled(false);
        // actionBar.setIcon(R.drawable.ic_action_search);

        LayoutInflater inflator = (LayoutInflater) this
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View v = inflator.inflate(R.layout.actionbar, null);

        actionBar.setCustomView(v);

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                Android.R.layout.simple_dropdown_item_1line, COUNTRIES);
        AutoCompleteTextView textView = (AutoCompleteTextView) v
                .findViewById(R.id.editText1);
        textView.setAdapter(adapter);

    }

}

et votre mise en page:

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent"
    Android:gravity="center" >

    <TextView
        Android:id="@+id/textView1"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="Action Bar:"
        Android:textAppearance="?android:attr/textAppearanceMedium"
        Android:textColor="#FFFFFF" />

    <AutoCompleteTextView
        Android:id="@+id/editText1"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:ems="10"
        Android:imeOptions="actionSearch"
        Android:inputType="textAutoComplete|textAutoCorrect"
        Android:textColor="#FFFFFF" >

        <requestFocus />
    </AutoCompleteTextView>

</LinearLayout>

Édité:

Veuillez vérifier ceci et ceci lien cela peut vous aider. le code est ici .

34
Dhaval Parmar

J'ai donc dû le faire pour la version v7 et j'ai été consterné de constater que je ne pouvais pas simplement configurer l'adaptateur avec un ArrayAdapter.

Je ne voulais pas utiliser un AutoCompleteTextView stock (comme le fait le meilleur commentateur ici), car alors vous manquez un certain nombre de fonctionnalités élégantes de SearchView, comme la petite icône de recherche et le bouton x.

J'ai donc étendu SearchView et obtenu ceci:

public class ArrayAdapterSearchView extends SearchView {

private SearchView.SearchAutoComplete mSearchAutoComplete;

public ArrayAdapterSearchView(Context context) {
    super(context);
    initialize();
}

public ArrayAdapterSearchView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initialize();
}

public void initialize() {
    mSearchAutoComplete = (SearchAutoComplete) findViewById(Android.support.v7.appcompat.R.id.search_src_text);
    this.setAdapter(null);
    this.setOnItemClickListener(null);
}

@Override
public void setSuggestionsAdapter(CursorAdapter adapter) {
    // don't let anyone touch this
}

public void setOnItemClickListener(OnItemClickListener listener) {
    mSearchAutoComplete.setOnItemClickListener(listener);
}

public void setAdapter(ArrayAdapter<?> adapter) {
    mSearchAutoComplete.setAdapter(adapter);
}

public void setText(String text) {
    mSearchAutoComplete.setText(text);
}

}

Vous pouvez utiliser ceci dans votre menu xml pour l'ActionBar comme ceci:

<menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto" >

<item
    Android:id="@+id/action_search"
    Android:icon="@Android:drawable/ic_menu_add"
    Android:title="TITLE"
    app:actionViewClass="com.yourpackage.ArrayAdapterSearchView"
    app:showAsAction="ifRoom|collapseActionView"/>

</menu>

Vous pouvez également ajouter une fonctionnalité de clic à la liste de saisie semi-automatique (par exemple, en définissant le texte sur EditText):

MenuItem searchItem = menu.findItem(R.id.action_search);
final ArrayAdapterSearchView searchView = (ArrayAdapterSearchView)searchItem.getActionView();
searchView.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

        searchView.setText(adapter.getItem(position).toString());

    }
});

Et voici une version similaire pour l'ancien Android.widget.SearchView ordinaire:

public class ArrayAdapterSearchView extends SearchView {

private AutoCompleteTextView mSearchAutoComplete;

public ArrayAdapterSearchView(Context context) {
    super(context);
    initialize();
}

public ArrayAdapterSearchView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initialize();
}

public void initialize() {
    mSearchAutoComplete = (AutoCompleteTextView) findViewById(getResources().getIdentifier("Android:id/search_src_text", null, null));
    setAutoCompleSuggestionsAdapter(null);
    setOnItemClickListener(null);
}

@Override
public void setSuggestionsAdapter(CursorAdapter adapter) {
    throw new UnsupportedOperationException("Please use setAutoCompleSuggestionsAdapter(ArrayAdapter<?> adapter) instead");
}

public void setOnItemClickListener(AdapterView.OnItemClickListener listener) {
    mSearchAutoComplete.setOnItemClickListener(listener);
}

public void setAutoCompleSuggestionsAdapter(ArrayAdapter<?> adapter) {
    mSearchAutoComplete.setAdapter(adapter);
}

public void setText(String text) {
    mSearchAutoComplete.setText(text);
}

}
39
user901309

Voici une méthode alternative utilisant CursorAdapter:

ExampleActivity.Java

private Menu menu;

@Override
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public boolean onCreateOptionsMenu(Menu menu) {

    getMenuInflater().inflate(R.menu.example, menu);

    this.menu = menu;

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {

        SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);

        SearchView search = (SearchView) menu.findItem(R.id.search).getActionView();

        search.setSearchableInfo(manager.getSearchableInfo(getComponentName()));

        search.setOnQueryTextListener(new OnQueryTextListener() { 

            @Override 
            public boolean onQueryTextChange(String query) {

                loadHistory(query);

                return true; 

            } 

        });

    }

    return true;

}

// History
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void loadHistory(String query) {

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {

        Cursor cursor = db.rawQuery("SELECT * FROM items", null); // Example database query

        SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);

        final SearchView search = (SearchView) menu.findItem(R.id.search).getActionView();

        search.setSearchableInfo(manager.getSearchableInfo(getComponentName()));

        search.setSuggestionsAdapter(new ExampleAdapter(this, cursor, items));

    }

}

Vous devez maintenant créer un adaptateur étendu à partir de CursorAdapter:

ExampleAdapter.Java

public class ExampleAdapter extends CursorAdapter {

    private List<String> items;

    private TextView text;

    public ExampleAdapter(Context context, Cursor cursor, List<String> items) {

        super(context, cursor, false);

        this.items = items;

    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {

        text.setText(cursor.getString(cursor.getColumnIndex("text"))); // Example column index

    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View view = inflater.inflate(R.layout.item, parent, false);

        text = (TextView) view.findViewById(R.id.text);

        return view;

    }

}

Remarque: lorsque vous importez CursorAdapter n'importez pas la Android, importez la norme Android.widget.CursorAdapter au lieu.

L'adaptateur nécessitera également une disposition personnalisée:

res/layout/item.xml

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent">

    <TextView
        Android:id="@+id/item"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content" />

</RelativeLayout>

Vous pouvez désormais personnaliser les éléments de la liste en ajoutant du texte ou des images supplémentaires à la mise en page et en les remplissant de données dans l'adaptateur. Vous avez maintenant besoin d'un élément de menu SearchView:

res/menu/example.xml

<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">

    <item
        Android:id="@+id/search"
        Android:title="@string/search"
        Android:showAsAction="ifRoom"
        Android:actionViewClass="Android.widget.SearchView" />

</menu>

Créez ensuite une configuration consultable:

res/xml/searchable.xml

<searchable xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:label="@string/search"
    Android:hint="@string/search" >
</searchable>

Enfin, ajoutez ceci dans la balise d'activité appropriée dans le fichier manifeste:

AndroidManifest.xml

<intent-filter>
    <action Android:name="Android.intent.action.SEARCH" />
</intent-filter>

<meta-data
    Android:name="Android.app.default_searchable"
    Android:value="com.example.ExampleActivity" />
<meta-data
    Android:name="Android.app.searchable"
    Android:resource="@xml/searchable" />

Veuillez noter: le @string/search la chaîne utilisée dans les exemples doit être définie dans values ​​/ strings.xml , n'oubliez pas non plus de mettre à jour la référence à com.example pour votre projet.

Voici le tutoriel d'origine pour référence:

http://tpbapp.com/Android-development/Android-action-bar-searchview-tutorial

8
tpbapp

Oui c'est possible. Créez une table (comme dans une base de données SQLite) pour vos suggestions et formatez la table avec les colonnes requises.

Voir ce lien

6
Arun C

J'étais également confronté à ce problème pour la vue de recherche de saisie automatique et le corriger sans utiliser de mise en page supplémentaire et de vue de texte de saisie automatique, il existe une classe appelée SearchAutoComplete. J'ai utilisé cela pour obtenir la fonction de saisie automatique, il suffit de mettre un simple adaptateur de liste qui contient une liste de tableaux d'éléments à suggérer avec la vue de recherche. Réglez l'adaptateur sur votre SearchAutoComplete et la fonction de saisie automatique fonctionnera ci-dessous est mon code. N'oubliez pas que vous n'avez pas à ajouter de mise en page personnalisée. Remplacez simplement votre méthode onCreateOptionsMenu (...) par le code mien:

    @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);

MenuItem searchItem = menu.findItem(R.id.search);
SearchView mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);

SearchAutoComplete searchAutoComplete = (SearchAutoComplete)     mSearchView.findViewById(Android.support.v7.appcompat.R.id.search_src_text);

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
Android.R.layout.simple_dropdown_item_1line, itemArrayList);
searchAutoComplete.setAdapter(adapter);

SearchManager searchManager =
(SearchManager) getSystemService(this.SEARCH_SERVICE);
mSearchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
return true;
}

En cliquant sur l'élément suggéré, l'élément devrait apparaître dans la vue de recherche, alors ajoutez le code ci-dessous juste après avoir défini votre adaptateur sur searchAutoComplete dans la méthode onCreateOptionmenu (...)

  searchAutoComplete.setOnItemClickListener(new OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
    long id) {
    // TODO Auto-generated method stub

    String searchString=(String)parent.getItemAtPosition(position);
    searchAutoComplete.setText(""+searchString);
    Toast.makeText(MainActivity.this, "you clicked "+searchString, Toast.LENGTH_LONG).show();

    }
    });
5
HAXM
    SearchAutoComplete searchAutoComplete = mSearchView.findViewById(androidx.appcompat.R.id.search_src_text);

pour la version androidx

1
Akgun Studio

Vous pouvez le faire avec un CursorAdapter via quelque chose comme:

MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);

searchView.setSuggestionsAdapter(adapter);
1
user901309