webentwicklung-frage-antwort-db.com.de

Implementieren von SearchView in der Aktionsleiste

Ich muss SearchView aus meinem arrayList<String> Erstellen und die Vorschläge in der Dropdown-Liste genauso anzeigen

enter image description here

Ich suche nach Tutorials, die Schritt für Schritt erklären, wie man ein SearchView in einer Aktionsleiste erstellt.

Ich habe die Dokumentation gelesen und folge dem Beispiel von Google, aber es war für mich nicht nützlich.

Ich habe die Suche erstellt

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <item Android:id="@+id/action_search"
          Android:title="Search"
          Android:icon="@Android:drawable/ic_menu_search"
          Android:showAsAction="always"
          Android:actionViewClass="Android.widget.SearchView" />
</menu>`

Aber ich weiß nicht, wie ich die Parameter des Strings-Arrays einstellen soll. Ich habe versucht, das Ergebnis in einer anderen Aktivität abzurufen, aber es funktioniert nicht.

79
Matteo

Es hat eine Weile gedauert, eine Lösung dafür zu finden, aber wir haben festgestellt, dass dies der einfachste Weg ist, es so zum Laufen zu bringen, wie Sie es beschreiben. Es gibt bessere Möglichkeiten, dies zu tun, aber da Sie Ihren Aktivitätscode nicht veröffentlicht haben, muss ich improvisieren und davon ausgehen, dass Sie zu Beginn Ihrer Aktivität eine Liste wie die folgende haben:

private List<String> items = db.getItems();

ExampleActivity.Java

private List<String> items;

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
        String[] columns = new String[] { "_id", "text" };
        Object[] temp = new Object[] { 0, "default" };

        MatrixCursor cursor = new MatrixCursor(columns);

        for(int i = 0; i < items.size(); i++) {

            temp[0] = i;
            temp[1] = items.get(i);replaced s with i as s not used anywhere.

            cursor.addRow(temp);

        }

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

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

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

    }

}

Jetzt müssen Sie einen Adapter erstellen, der von CursorAdapter erweitert wurde:

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(items.get(cursor.getPosition()));

    }

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

    }

}

Besser ist es, wenn Ihre Listendaten aus einer Datenbank stammen. Sie können die von den Datenbankfunktionen zurückgegebenen Cursor direkt an ExampleAdapter übergeben und den Spaltentext in der entsprechenden Spaltenauswahl anzeigen das TextView, auf das im Adapter verwiesen wird.

Bitte beachten Sie: Wenn Sie CursorAdapter importieren, importieren Sie nicht die Android Support-Version, sondern den Standard Android.widget.CursorAdapter.

Der Adapter erfordert auch ein benutzerdefiniertes Layout:

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>

Sie können nun Listenelemente anpassen, indem Sie dem Layout zusätzliche Text- oder Bildansichten hinzufügen und sie mit Daten im Adapter füllen.

Dies sollte alles sein, aber wenn Sie dies noch nicht getan haben, benötigen Sie einen SearchView-Menüpunkt:

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>

Dann erstelle eine durchsuchbare Konfiguration:

res/xml/searchable.xml

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

Fügen Sie dies schließlich in das entsprechende Aktivitäts-Tag in der Manifest-Datei ein:

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

Bitte beachten Sie: Die in den Beispielen verwendete Zeichenfolge @string/search Sollte in values ​​/ strings.xml definiert werden. Vergessen Sie auch nicht, die Referenz auf com.example Für Ihre Zeichenfolge zu aktualisieren Projekt.

125
tpbapp

Wenn jemand anderes ein nullptr für die searchview-Variable hat, habe ich herausgefunden, dass das Item-Setup ein kleines bisschen anders ist:

alt:

Android:showAsAction="ifRoom"
Android:actionViewClass="Android.widget.SearchView"

neu:

app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="androidx.appcompat.widget.SearchView"

vor Android x:

app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="Android.support.v7.widget.SearchView"

Weitere Informationen finden Sie in der aktualisierten Dokumentation unter hier zu finden .

49
Grease

SearchDialog oder SearchWidget?

Wenn es um die Implementierung einer Suchfunktion geht, gibt es zwei Lösungsvorschläge by official Android Entwicklerdokumentation).
Sie können entweder ein SearchDialog oder ein SearchWidget verwenden. .
Ich werde die Implementierung der Suchfunktion mit SearchWidget erläutern.

Wie geht das mit dem Such-Widget?

Ich werde die Suchfunktionen in einer RecyclerView mit SearchWidget erläutern. Es ist ziemlich einfach.

Befolgen Sie einfach diese 5 einfachen Schritte

1) Fügen Sie searchView im Menü hinzu

Sie können SearchView als actionView im Menü mit hinzufügen

app: useActionClass = "Android.support.v7.widget.SearchView".

<menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
   xmlns:app="http://schemas.Android.com/apk/res-auto"
   xmlns:tools="http://schemas.Android.com/tools"
   tools:context="rohksin.com.searchviewdemo.MainActivity">
   <item
       Android:id="@+id/searchBar"
       app:showAsAction="always"
       app:actionViewClass="Android.support.v7.widget.SearchView"
   />
</menu>

2) Richten Sie den SerchView - Hinweistext, den Listener usw

Sie sollten SearchView in der onCreateOptionsMenu(Menu menu) -Methode initialisieren.

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

        MenuItem searchItem = menu.findItem(R.id.searchBar);

        SearchView searchView = (SearchView) searchItem.getActionView();
        searchView.setQueryHint("Search People");
        searchView.setOnQueryTextListener(this);
        searchView.setIconified(false);

        return true;
   }

3) Implementieren Sie SearchView.OnQueryTextListener in Ihre Aktivität

OnQueryTextListener hat zwei abstrakte Methoden

  1. onQueryTextSubmit(String query)
  2. onQueryTextChange(String newText

Ihr Aktivitätsskelett würde also so aussehen

YourActivity extends AppCompatActivity implements SearchView.OnQueryTextListener{

     public boolean onQueryTextSubmit(String query)

     public boolean onQueryTextChange(String newText) 

}

4) Implementieren Sie SearchView.OnQueryTextListener

Sie können die Implementierung für die abstrakten Methoden wie folgt bereitstellen

public boolean onQueryTextSubmit(String query) {

    // This method can be used when a query is submitted eg. creating search history using SQLite DB

    Toast.makeText(this, "Query Inserted", Toast.LENGTH_SHORT).show();
    return true;
}

@Override
public boolean onQueryTextChange(String newText) {

    adapter.filter(newText);
    return true;
}

5) Schreiben Sie eine Filtermethode in Ihren RecyclerView Adapter.

Wichtigster Teil. Sie können Ihre eigene Logik schreiben, um eine Suche durchzuführen.
Hier ist mein. Dieses Snippet zeigt die Liste der Namen, die den in SearchView eingegebenen Text enthält.

public void filter(String queryText)
{
    list.clear();

    if(queryText.isEmpty())
    {
       list.addAll(copyList);
    }
    else
    {

       for(String name: copyList)
       {
           if(name.toLowerCase().contains(queryText.toLowerCase()))
           {
              list.add(name);
           }
       }

    }

   notifyDataSetChanged();
}

Relevanter Link:

Voller Funktionscode in SearchView mit einer SQLite-Datenbank in dieser Musik-App

3
Rohit Singh

Verwenden Sie für Searchview diesen Code

  1. Für XML

    <Android.support.v7.widget.SearchView
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:id="@+id/searchView">
    
    </Android.support.v7.widget.SearchView>
    

  2. In deinem Fragment oder deiner Aktivität

    package com.example.user.salaryin;
    
    import Android.app.ProgressDialog;
    import Android.os.Bundle;
    import Android.support.v4.app.Fragment;
    import Android.support.v4.view.MenuItemCompat;
    import Android.support.v7.widget.GridLayoutManager;
    import Android.support.v7.widget.LinearLayoutManager;
    import Android.support.v7.widget.RecyclerView;
    import Android.support.v7.widget.SearchView;
    import Android.view.LayoutInflater;
    import Android.view.Menu;
    import Android.view.MenuInflater;
    import Android.view.MenuItem;
    import Android.view.View;
    import Android.view.ViewGroup;
    import Android.widget.Toast;
    import com.example.user.salaryin.Adapter.BusinessModuleAdapter;
    import com.example.user.salaryin.Network.ApiClient;
    import com.example.user.salaryin.POJO.ProductDetailPojo;
    import com.example.user.salaryin.Service.ServiceAPI;
    import Java.util.ArrayList;
    import Java.util.List;
    import retrofit2.Call;
    import retrofit2.Callback;
    import retrofit2.Response;
    
    
    public class OneFragment extends Fragment implements SearchView.OnQueryTextListener {
    
    RecyclerView recyclerView;
    RecyclerView.LayoutManager layoutManager;
    ArrayList<ProductDetailPojo> arrayList;
    BusinessModuleAdapter adapter;
    private ProgressDialog pDialog;
    GridLayoutManager gridLayoutManager;
    SearchView searchView;
    
    public OneFragment() {
        // Required empty public constructor
    }
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
    
        View rootView = inflater.inflate(R.layout.one_fragment,container,false);
    
        pDialog = new ProgressDialog(getActivity());
        pDialog.setMessage("Please wait...");
    
    
        searchView=(SearchView)rootView.findViewById(R.id.searchView);
        searchView.setQueryHint("Search BY Brand");
        searchView.setOnQueryTextListener(this);
    
        recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerView);
        layoutManager = new LinearLayoutManager(this.getActivity());
        recyclerView.setLayoutManager(layoutManager);
        gridLayoutManager = new GridLayoutManager(this.getActivity().getApplicationContext(), 2);
        recyclerView.setLayoutManager(gridLayoutManager);
        recyclerView.setHasFixedSize(true);
        getImageData();
    
    
        // Inflate the layout for this fragment
        //return inflater.inflate(R.layout.one_fragment, container, false);
        return rootView;
    }
    
    
    private void getImageData() {
        pDialog.show();
        ServiceAPI service = ApiClient.getRetrofit().create(ServiceAPI.class);
        Call<List<ProductDetailPojo>> call = service.getBusinessImage();
    
        call.enqueue(new Callback<List<ProductDetailPojo>>() {
            @Override
            public void onResponse(Call<List<ProductDetailPojo>> call, Response<List<ProductDetailPojo>> response) {
                if (response.isSuccessful()) {
                    arrayList = (ArrayList<ProductDetailPojo>) response.body();
                    adapter = new BusinessModuleAdapter(arrayList, getActivity());
                    recyclerView.setAdapter(adapter);
                    pDialog.dismiss();
                } else if (response.code() == 401) {
                    pDialog.dismiss();
                    Toast.makeText(getActivity(), "Data is not found", Toast.LENGTH_SHORT).show();
                }
    
            }
    
            @Override
            public void onFailure(Call<List<ProductDetailPojo>> call, Throwable t) {
                Toast.makeText(getActivity(), t.getMessage(), Toast.LENGTH_SHORT).show();
                pDialog.dismiss();
    
            }
        });
    }
    
       /* @Override
        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        getActivity().getMenuInflater().inflate(R.menu.menu_search, menu);
        MenuItem menuItem = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) MenuItemCompat.getActionView(menuItem);
        searchView.setQueryHint("Search Product");
        searchView.setOnQueryTextListener(this);
    }*/
    
    @Override
    public boolean onQueryTextSubmit(String query) {
        return false;
    }
    
    @Override
    public boolean onQueryTextChange(String newText) {
        newText = newText.toLowerCase();
        ArrayList<ProductDetailPojo> newList = new ArrayList<>();
        for (ProductDetailPojo productDetailPojo : arrayList) {
            String name = productDetailPojo.getDetails().toLowerCase();
    
            if (name.contains(newText) )
                newList.add(productDetailPojo);
            }
        adapter.setFilter(newList);
        return true;
       }
    }
    
  3. In der Adapterklasse

     public void setFilter(List<ProductDetailPojo> newList){
        arrayList=new ArrayList<>();
        arrayList.addAll(newList);
        notifyDataSetChanged();
    }
    
1
Neeraj Gupta