SearchView işlem çubuğunda uygulama


83

Ben oluşturmak için gereken SearchViewne biz den arrayList<String>açılır liste Aynı şey bu önerileri ve göstermek

görüntü açıklamasını buraya girin

SearchViewBir eylem çubuğunda nasıl oluşturulacağını adım adım açıklayan öğreticiler arıyorum .

Dokümanları okudum ve google örneğini izledim ama benim için yararlı olmadı.

Aramayı ben yarattım

<?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>`

Ama dizge dizisinin parametrelerini nasıl ayarlayacağımı bilmiyorum. Sonucu farklı bir Aktivitede almaya çalıştım ama işe yaramadı.


6
Denediğiniz her şeyi olabildiğince ayrıntılı olarak göndermelisiniz. Örnek kod içeren belirli sorular, daha hızlı ve daha anlamlı yanıtlar alma eğilimindedir.
Collin Flynn

Yanıtlar:


128

Bunun için bir çözüm bulmak biraz zaman aldı, ancak bunun tarif ettiğiniz şekilde çalışmasını sağlamanın en kolay yolu olduğunu anladım. Bunu yapmanın daha iyi yolları olabilir, ancak etkinlik kodunuzu göndermediğiniz için doğaçlama yapmam ve etkinliğinizin başında buna benzer bir listenizin olduğunu varsaymam gerekecek:

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

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

    }

}

Şimdi aşağıdakilerden genişletilmiş bir adaptör oluşturmanız gerekir 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(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;

    }

}

Bunu yapmanın daha iyi bir yolu, liste verileriniz bir veritabanından geliyorsa, Cursorveritabanı işlevleri tarafından döndürülenleri doğrudan bağdaştırıcıda referans ExampleAdapterverilen sütun metnini görüntülemek için ilgili sütun seçiciyi kullanabilirsiniz TextView.

Lütfen unutmayın: içe CursorAdapteraktarırken Android destek sürümünü içe aktarmayın, android.widget.CursorAdapterbunun yerine standardı içe aktarın .

Adaptör ayrıca özel bir düzen gerektirecektir:

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>

Artık düzene ek metin veya resim görünümleri ekleyerek ve bunları adaptördeki verilerle doldurarak liste öğelerini özelleştirebilirsiniz.

Hepsi bu olmalı, ancak bunu daha önce yapmadıysanız, bir SearchView menü öğesine ihtiyacınız vardır:

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>

Ardından aranabilir bir yapılandırma oluşturun:

res / xml / aranabilir.xml

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

Son olarak, bunu manifest dosyasındaki ilgili etkinlik etiketine ekleyin:

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

Lütfen dikkat: @string/searchÖrneklerde kullanılan dizge değerler / strings.xml'de tanımlanmalıdır , ayrıca com.exampleprojeniz için referansı güncellemeyi unutmayın .


3
Merhaba, ama bir şüphem, umarım bu konuda bana yardım edersin. Filtreye bir harf yazarsam, filtre sonuçlarım olmasına rağmen, birden fazla ise hiçbir şey görüntülenmez. o zaman yalnızca görüntülenir. neden?
Naruto

Merhaba, belki stillerinizi EditText veya AutoCompleteTextView ile ilgili herhangi bir şey için kontrol edin, çünkü otomatik tamamlamayı göstermeden önce girilmesi gereken varsayılan karakter sayısını ayarlayabilirsiniz. Aslında varsayılanın 2 karakter olduğunu düşünüyorum, bu yüzden değiştirmek için bunu stillere eklemeniz gerekebilir.
tpbapp

Merhaba, geliştirirken, arama görünümüyle ilgili bir sorunla daha karşılaştım. Eğer açılır menüde daha fazla öğe görüntülersem, örneğin: 3 metin görünümü, öğenin boyutu artar, böylece i.stack.imgur.com/d7t3A.png gibi kaydırırsam arama öğeleri klavyede akar . Bu, metnin boyutunu büyütürsem veya öğeye daha fazla görünüm eklersem olur. Varsayılan davranış mı?
Naruto

Tekrar merhaba, hayır bu olmamalı. Görünüşe göre, projede zaten SearchView'daki AutoCompleteTextView ile çakışan çok sayıda kodunuz var veya belki klavye yazılımında ve uygulamada veya bu davranışa neden olan bir eklentide bir sorun var. Varsayılan davranış böyle bir şey olmalı stackoverflow.com/questions/22116237/... bu kişi hariç aslında krokisi soruyor değil klavyenin arkasında gizlenmiş.
tpbapp

3
@tpbapp Ben zaten anladım. Öneri listesinin görünmemesinin nedeni, kodunuzda ve yöntemlerinde search.setSearchableInfo(manager.getSearchableInfo(getComponentName()));iki kez çağırmış olmanızdır . Bu yüzden SearchView ve SearchManager global değişkenini yapıyorum ve yalnızca bir kez çağırıyorum . Ve öneri listem artık mükemmel çalışıyor. Kodunuzu gözden geçirmenizi öneririm. onCreateOptionsMenu()loadHistory()getSearchableInfo()onCreateOptionsMenu()
Hafizh Herdi

53

Arama görünümü değişkeninde başka biri nullptr'ye sahipse, öğe kurulumunun biraz farklı olduğunu öğrendim:

eski:

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

yeni:

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

android öncesi x:

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

Daha fazla bilgi için, güncellenmiş belgeleri burada bulunmaktadır .


3
Teşekkür ederim. Tam da özlediğim şey. :-)
Morten E. Rasmussen

Teşekkürler, bu basit ve yardımcı oldu.
Muhammed

1
app:actionViewClass="androidx.appcompat.widget.SearchView"androidx için
HendraWD

4

SearchDialog veya SearchWidget?

Bir arama işlevini uygulamaya gelince, resmi Android Geliştirici Belgeleri tarafından önerilen iki yaklaşım vardır .
Bir SearchDialog veya bir SearchWidget kullanabilirsiniz .
SearchWidget kullanarak Arama işlevinin uygulanmasını açıklayacağım.

Arama widget'ı ile nasıl yapılır?

RecyclerView'da SearchWidget kullanarak arama işlevini açıklayacağım. Oldukça basit.

Sadece bu 5 basit adımı izleyin

1) Menüye searchView öğesi ekleyin

Ekleyebilir SearchViewolarak eklenebilir actionViewkullanarak menüde

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) SerchView Hint metni, dinleyici vb. Ayarlayın.

onCreateOptionsMenu(Menu menu)Yöntemde SearchView'i başlatmalısınız .

  @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) SearchView.OnQueryTextListener'ı Aktivitenize uygulayın

OnQueryTextListener iki soyut yöntemi vardır

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

Yani Aktivite iskeletiniz şöyle görünür

YourActivity extends AppCompatActivity implements SearchView.OnQueryTextListener{

     public boolean onQueryTextSubmit(String query)

     public boolean onQueryTextChange(String newText) 

}

4) SearchView.OnQueryTextListener'ı uygulayın

Bunun gibi soyut yöntemler için uygulama sağlayabilirsiniz.

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) RecyclerView Adaptörünüze bir filtre yöntemi yazın.

En önemli kısım. Arama yapmak için kendi mantığınızı yazabilirsiniz.
İşte benim. Bu pasaj, yazılan metni içeren Ad listesini gösterir.SearchView

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

İlgili bağlantı:

Bu Müzik Uygulamasında bir SQLite veritabanıyla SearchView üzerinde tam çalışma kodu


1

SearchviewBu kodu kullanmak için

  1. XML için

    <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. Parçanızda veya Faaliyetinizde

    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. Adaptör sınıfında

     public void setFilter(List<ProductDetailPojo> newList){
        arrayList=new ArrayList<>();
        arrayList.addAll(newList);
        notifyDataSetChanged();
    }
    
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.