एक्शन बार में SearchView को लागू करना


83

मैं बनाने की जरूरत SearchViewमेरी से arrayList<String>और ड्रॉप-डाउन सूची में एक ही इस में सुझाव दिखाने

यहां छवि विवरण दर्ज करें

मैं उन ट्यूटोरियल की तलाश करता हूं जो कदम से कदम समझाते हैं कि SearchViewएक्शन बार में निर्माण कैसे करें ।

मैंने प्रलेखन पढ़ा है और उदाहरण के लिए गूगल का अनुसरण किया है लेकिन यह मेरे लिए उपयोगी नहीं था।

मैंने खोज बनाई है

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

लेकिन मुझे नहीं पता कि स्ट्रिंग के सरणी के मापदंडों को कैसे सेट किया जाए। मैंने एक अलग गतिविधि में परिणाम प्राप्त करने की कोशिश की, लेकिन काम नहीं किया।


6
जितना संभव हो सके उतना सब कुछ पोस्ट करना चाहिए। नमूना कोड के साथ विशिष्ट प्रश्न तेजी से, अधिक सार्थक उत्तर प्राप्त करते हैं।
कोलिन फ्लिन

जवाबों:


128

इसके लिए एक साथ समाधान करने में थोड़ा समय लगा, लेकिन यह पाया है कि यह उस तरीके से काम करने का सबसे आसान तरीका है जैसा आप वर्णन करते हैं। ऐसा करने के लिए बेहतर तरीके हो सकते हैं, लेकिन चूंकि आपने अपना गतिविधि कोड पोस्ट नहीं किया है, इसलिए मुझे आपकी गतिविधि की शुरुआत में इस तरह की एक सूची सुधारनी होगी और माननी होगी:

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

    }

}

अब आप एक एडाप्टर से बढ़ाया बनाने की जरूरत 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;

    }

}

ऐसा करने का एक बेहतर तरीका यह है कि यदि आपका सूची डेटा किसी डेटाबेस से है, तो आप Cursorसीधे एडेप्टर फ़ंक्शन ExampleAdapterमें दिए गए कॉलम टेक्स्ट को प्रदर्शित करने के लिए संबंधित कॉलम चयनकर्ता का उपयोग कर सकते हैं TextView

कृपया ध्यान दें: जब आप आयात CursorAdapterकरते हैं तो Android समर्थन संस्करण आयात नहीं करते हैं, android.widget.CursorAdapterइसके बजाय मानक आयात करें ।

एडाप्टर को एक कस्टम लेआउट की भी आवश्यकता होगी:

रेस / लेआउट / 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>

अब आप लेआउट में अतिरिक्त पाठ या छवि दृश्य जोड़कर और एडॉप्टर में डेटा के साथ उन्हें पॉपअप करके सूची आइटम को अनुकूलित कर सकते हैं।

यह सब होना चाहिए, लेकिन अगर आपने ऐसा नहीं किया है, तो आपको पहले से ही एक SearchView मेनू आइटम की आवश्यकता है:

रेस / मेनू / 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>

फिर खोज योग्य विन्यास बनाएँ:

रेस / xml / searchable.xml

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

अंत में इसे संबंधित गतिविधि टैग में प्रकट फ़ाइल में जोड़ें:

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

कृपया ध्यान दें: @string/searchउदाहरणों में उपयोग की जाने वाली स्ट्रिंग को मान / स्ट्रिंग्स . xml में परिभाषित किया जाना चाहिए , com.exampleअपनी परियोजना के संदर्भ को अपडेट करना भी न भूलें ।


3
हाय, लेकिन एक संदेह है, मुझे आशा है कि आप इस पर मेरी मदद करेंगे। यदि मैं फ़िल्टर पर एक अक्षर टाइप करता हूँ, हालाँकि मेरे पास फ़िल्टर परिणाम हैं, तो कुछ भी प्रदर्शित नहीं होगा, यदि इसका अधिक है तो एक। तभी यह प्रदर्शित करता है। क्यों?
नारुतो

नमस्ते, शायद EditText या AutoCompleteTextView से संबंधित किसी भी चीज़ के लिए अपनी शैलियों की जांच करें क्योंकि आप उन वर्णों की डिफ़ॉल्ट संख्या सेट कर सकते हैं, जिन्हें स्वत: पूर्ण दिखाने से पहले दर्ज करने की आवश्यकता होती है। वास्तव में मुझे लगता है कि डिफ़ॉल्ट 2 वर्ण है, इसलिए यह ऐसा हो सकता है कि इसे बदलने के लिए आपको इसे शैलियों में जोड़ना होगा।
tpbapp

नमस्ते, जबकि मैं विकसित खोज के एक और मुद्दे के पार आया था। अगर मैं ड्रॉप डाउन में अधिक आइटम प्रदर्शित करता हूं, जैसे: 3 टेक्स्टव्यू, तो आइटम का आकार बढ़ जाता है, इसलिए यदि मैं i.stack.imgur.com/d7t3A.png की तरह स्क्रॉल करता हूं , तो खोज आइटम कीबोर्ड पर बहते हैं । ऐसा तब होता है जब मैं पाठ का आकार बढ़ाता हूं या आइटम में अधिक विचार जोड़ता हूं। क्या यह डिफ़ॉल्ट व्यवहार है?
नारुतो

फिर से हाय, नहीं जो नहीं होना चाहिए। ऐसा लगता है कि आपके पास प्रोजेक्ट में पहले से ही बहुत सारे कोड हैं जो कि SearchView में AutoCompleteTextView के साथ हस्तक्षेप कर रहा है या शायद कीबोर्ड सॉफ़्टवेयर के साथ कुछ गड़बड़ है, और इस व्यवहार के कारण ऐप या एक प्लगइन है। डिफ़ॉल्ट व्यवहार कुछ इस तरह होना चाहिए stackoverflow.com/questions/22116237/… इस व्यक्ति को छोड़कर वास्तव में पूछ रहा है कि इसे कीबोर्ड के पीछे छिपाए नहीं जाने के लिए कैसे प्राप्त किया जाए ।
tpbapp

3
@tpbapp मैं पहले से ही इसका पता लगा रहा हूं। कारण सुझाव सूची दिखाई नहीं दे रही है क्योंकि आपके कोड में आपने search.setSearchableInfo(manager.getSearchableInfo(getComponentName()));दो बार onCreateOptionsMenu()और loadHistory()विधियों को बुलाया था । इसलिए मैं SearchView और SearchManager को वैश्विक चर बनाता हूं, और केवल getSearchableInfo()एक बार ही बुलाया जाता है onCreateOptionsMenu()। और मेरी सुझाव सूची अब पूरी तरह से काम कर रही है। मैं आपको अपने कोड को संशोधित करने का सुझाव देता हूं।
हाफिजह हदी

53

अगर किसी और को खोज चर पर एक अशक्त होने पर, मुझे पता चला कि आइटम सेटअप एक अलग सा है:

पुराना:

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

नया:

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

प्री-एंड्रॉइड x:

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

अधिक जानकारी के लिए, यह अद्यतन प्रलेखन यहाँ स्थित है


3
धन्यवाद। बस जो मुझे याद आ रहा था। :-)
मोर्टन ई। रासमुसेन

धन्यवाद, जो सरल और सहायक था।
मुहम्मद

1
app:actionViewClass="androidx.appcompat.widget.SearchView"Androidx के लिए
हेंड्रीडब्ल्यू

4

SearchDialog या SearchWidget?

जब खोज की कार्यक्षमता को लागू करने की बात आती है तो आधिकारिक एंड्रॉइड डेवलपर प्रलेखन द्वारा दो सुझाए गए दृष्टिकोण होते हैं ।
आप या तो SearchDialog या SearchWidget का उपयोग कर सकते हैं ।
मैं SearchWidget का उपयोग करके खोज कार्यक्षमता के कार्यान्वयन की व्याख्या करने जा रहा हूं।

इसे सर्च विजेट के साथ कैसे करें?

मैं SearchWidget का उपयोग करके एक RecyclerView में खोज कार्यक्षमता की व्याख्या करूंगा। यह बहुत सीधा है।

बस इन 5 सरल चरणों का पालन करें

1) मेनू में searchView आइटम जोड़ें

आप जोड़ SearchViewसकते हैं actionViewमेनू का उपयोग कर के रूप में जोड़ा जा सकता है

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 संकेत पाठ, श्रोता आदि सेट करें

आपको onCreateOptionsMenu(Menu menu)विधि में SearchView को इनिशियलाइज़ करना चाहिए ।

  @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 को लागू करें

OnQueryTextListener दो सार विधियाँ हैं

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

तो आपकी गतिविधि कंकाल इस तरह दिखेगी

YourActivity extends AppCompatActivity implements SearchView.OnQueryTextListener{

     public boolean onQueryTextSubmit(String query)

     public boolean onQueryTextChange(String newText) 

}

4) SearchView.OnQueryTextListener को लागू करें

आप इस तरह अमूर्त तरीकों के लिए कार्यान्वयन प्रदान कर सकते हैं

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 एडाप्टर में एक फिल्टर विधि लिखें।

सबसे महत्वपूर्ण हिस्सा। आप खोज करने के लिए अपने तर्क लिख सकते हैं।
यह रहा मेरा। यह स्निपेट नाम की सूची दिखाता है जिसमें पाठ टाइप किया गया है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();
}

प्रासंगिक लिंक:

इस म्यूजिक ऐप में SQLite डेटाबेस के साथ SearchView पर पूर्ण कार्य कोड


1

के लिए Searchviewइन कोड का उपयोग

  1. 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. आपके टुकड़े या गतिविधि में

    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. एडॉप्टर क्लास में

     public void setFilter(List<ProductDetailPojo> newList){
        arrayList=new ArrayList<>();
        arrayList.addAll(newList);
        notifyDataSetChanged();
    }
    
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.