2012-07-23 6 views
9

मैंने एक खोज योग्य गतिविधि बनाई है। अब, मैं वेब सेवा से लिया गया खोज सुझाव जोड़ना चाहता हूं। मैं उन सुझावों को असीमित रूप से प्राप्त करना चाहता हूं। Adding Custom Suggestions के अनुसार मुझे क्वेरी विधि को ओवरराइड करने की आवश्यकता है, मेरी सुझाव खोज करें, अपना खुद का MatrixCursor बनाएं और इसे वापस करें। लेकिन यह समस्या है, सुझाव प्राप्त करने का मेरा अनुरोध एक असंकालिक रूप से एक है। इसलिए जब परिणाम क्वेरी विधि के दायरे से बाहर निकल जाता है।एंड्रॉइड: वेब से असीमित रूप से खोज सुझाव कैसे प्राप्त करें?

+0

खोज सुझाव द्वारा आप AutoCompleteTextView मतलब ?? –

+1

नहीं। मैं एंड्रॉइड खोज संवाद का उपयोग कर रहा हूं। दस्तावेज़ीकरण में वर्णन के रूप में: "एंड्रॉइड खोज संवाद या खोज विजेट का उपयोग करते समय, आप अपने आवेदन में डेटा से बनाए गए कस्टम खोज सुझाव प्रदान कर सकते हैं।" मैं जो करने की कोशिश कर रहा हूं वह सर्वर से उन सुझावों को प्राप्त करता है, डीबी से नहीं। – toko

उत्तर

0

मुझे हल करने के लिए सबसे नज़दीकी चीज है, एक ContentProvider का उपयोग करके और अपने प्रदाता के Query विधि पर नेटवर्क अनुरोध करें (भले ही यह सर्वोत्तम प्रथाओं के खिलाफ हो), परिणामस्वरूप आप MatrixCursor बना सकते हैं क्योंकि यह here और here दिखा रहा है।

मैं अभी भी SyncAdapter का उपयोग करने जैसे अन्य विकल्पों की खोज कर रहा हूं, जो कि केवल उन सुझावों के उपयोग के लिए जबरदस्त प्रतीत होता है जो कहीं और नहीं उपयोग किए जाते हैं।

एक अन्य विकल्प है कि मैं इस अतुल्यकालिक रूप से करने के लिए ले लिया एक AutoCompleteTextView, इस तरह आप एक कस्टम एडाप्टर, जहां getFilter समारोह लागू कर सकते हैं के रूप में यह this answer में दिखाया गया है बना सकते हैं उपयोग करने के लिए है।

+0

मैट्रिक्स कर्सर को उदाहरणों में दिखाए जाने के रूप में बनाना, समस्या को हल नहीं करता है क्योंकि मैं सर्वर से अतुल्यकालिक सुझाव प्राप्त करना चाहता हूं। – toko

+0

@toko कृपया मेरा उत्तर संपादित करें, मैंने एक और विकल्प जोड़ा, यह वह है जिसे मैंने अंत में लिया था, जो आपको वेब से डेटा प्राप्त करते समय आपके यूआई थ्रेड को अवरुद्ध नहीं करेगा। –

+0

समस्या यह है कि मैं AutoCompleteTextView का उपयोग नहीं कर रहा हूं। मैं खोज इंटरफ़ेस संवाद का उपयोग कर रहा हूं: http://developer.android.com/guide/topics/search/search-dialog.html – toko

1

ऐसा लगता है कि सुझाव सामग्री प्रदाता का अनुरोध यूआई थ्रेड पर नहीं चला है, वैसे भी, इस उत्तर के अनुसार: https://stackoverflow.com/a/12895381/621690। यदि आप अपना http अनुरोध बदल सकते हैं तो आप इसे क्वेरी विधि के अंदर अवरुद्ध कर सकते हैं। अनावश्यक अनुरोधों को रोकने के लिए बाधाओं या अन्य संकेतों (शायद कस्टम वाले) को सुनने में मदद मिल सकती है।

एक और विकल्प - यदि आप पहले से ही एसिंक्रोनस (जैसे कि आप रोबोसिस का उपयोग कर रहे हैं) के किसी भी अनुरोध कक्षा को बदलना नहीं चाहते हैं - तो बस मैट्रिक्स कर्सर संदर्भ को वापस लौटना चाहिए और बाद में इसे पॉप्युलेट करना चाहिए। सार कर्सर वर्ग पहले से ही पर्यवेक्षक पैटर्न लागू करता है और परिवर्तनों के मामले में अधिसूचना भेजता है। यदि खोज प्रणाली सुन रही है तो इसे डेटा में किसी भी बदलाव को संभालना चाहिए। मैंने अभी तक इसे स्वयं लागू नहीं किया है, इसलिए मैं पुष्टि नहीं कर सकता कि यह अच्छी तरह से काम करेगा जैसा कि मैंने इसे चित्रित किया है। (अधिक प्रेरणा के लिए कर्सर लोडर के स्रोत पर एक नज़र डालें।)

और, वैसे भी, कर्सर का पूरा बिंदु नहीं है? अन्यथा हम डेटा के साथ एक सूची वापस कर सकते हैं।

अद्यतन: मेरे लिए, मैट्रिक्स कर्सर का उपयोग करने से काम नहीं हुआ। इसके बजाए, मैंने दो अन्य समाधान लागू किए हैं:

  1. ऑटोकंपलेटटेक्स्टफिल्ड का उपयोग ArrayAdapter के कस्टम उप-वर्ग के साथ संयोजन में जो स्वयं फ़िल्टर के कस्टम उप-वर्ग का उपयोग करता है। विधि Filter#performFiltering() (जो मैं रिमोट सेवा में सिंक्रोनस कॉल के साथ ओवरराइड करता हूं) को असीमित रूप से कहा जाता है और यूआई थ्रेड अवरुद्ध नहीं होता है।
  2. सर्चविड्ज का उपयोग एक खोज योग्य सक्रियता और कस्टम ऐरेएडाप्टर (कस्टम फ़िल्टर के बिना) के साथ करना। जब खोज अभिप्राय में आता है, दूरदराज के अनुरोध करना शुरू कर दिया है (Robospice) और जब यह कॉलबैक के माध्यम से वापस आता है, मैं अपने ArrayAdapter<Tag> उपवर्ग पर निम्न कस्टम विधि कॉल:

    public void addTags(List<Tag> items) { 
        if (items != null && items.size() > 0) { 
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { 
          super.setNotifyOnChange(false); 
          for (Tag tag : items) { 
           super.add(tag); 
          } 
          super.notifyDataSetChanged(); 
         } else { 
          super.addAll(items); 
         } 
        } 
    } 
    

इस विधि को ट्रिगर का ख्याल रखता है एडाप्टर पर अधिसूचनाएं और इस प्रकार खोज परिणाम सूची।

+0

निश्चित रूप से सही विचार। मैं बिल्कुल ऐसा करने की कोशिश कर रहा हूं, लेकिन ऐसा लगता है कि एंड्रॉइड के खोज सुझाव कर्सर परिवर्तनों को नहीं सुनते हैं। :/विशेष रूप से, मैं 'ContentResolver.notifyChange()' को कॉल कर रहा हूं, लेकिन मुझे नहीं लगता कि एंड्रॉइड का ['सुझाव एडाप्टर'] (https://android.googlesource.com/platform/frameworks/base/+/jb- रिलीज/कोर/जावा/एंड्रॉइड/विजेट/सुझाव एडाप्टर.जावा) 'रजिस्टरकंटेंट ऑब्सर्वर() 'कॉल करता है। कोई विचार? क्या मुझे कुछ याद आ रही है? – ryan

+0

यह सही विचार की तरह लग रहा था लेकिन यह काम नहीं किया (कम से कम मेरे लिए नहीं)। मेरे वर्तमान समाधान के साथ मेरा जवाब अपडेट किया गया। – Risadinha

+0

अद्यतन के लिए धन्यवाद! उन मौजूदा समाधान खोज परिणामों के लिए समझ में आता है। मैं अभी भी लौटने के बाद [search _suggestions_] (http://developer.android.com/guide/topics/search/adding-custom-suggestions.html) अपडेट करने का एक तरीका ढूंढ रहा हूं, हालांकि। मुझे संदेह है कि कोई रास्ता नहीं हो सकता ... लेकिन यदि आप एक को जानते हैं, तो कृपया हमें बताएं! – ryan

0

यहाँ एक नेटवर्क सेवा (मैं रेट्रोफिट प्रयुक्त) से आने वाले सुझावों के साथ 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_search_activity, menu); 

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

     final CursorAdapter suggestionAdapter = new SimpleCursorAdapter(this, 
       android.R.layout.simple_list_item_1, 
       null, 
       new String[]{SearchManager.SUGGEST_COLUMN_TEXT_1}, 
       new int[]{android.R.id.text1}, 
       0); 
     final List<String> suggestions = new ArrayList<>(); 

     searchView.setSuggestionsAdapter(suggestionAdapter); 
     searchView.setOnSuggestionListener(new SearchView.OnSuggestionListener() { 
      @Override 
      public boolean onSuggestionSelect(int position) { 
       return false; 
      } 

      @Override 
      public boolean onSuggestionClick(int position) { 
       searchView.setQuery(suggestions.get(position), false); 
       searchView.clearFocus(); 
       doSearch(suggestions.get(position)); 
       return true; 
      } 
     }); 

     searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { 

      @Override 
      public boolean onQueryTextSubmit(String query) { 
       return false; 
      } 

      @Override 
      public boolean onQueryTextChange(String newText) { 

       MyApp.autocompleteService.search(newText, new Callback<Autocomplete>() { 
        @Override 
        public void success(Autocomplete autocomplete, Response response) { 
         suggestions.clear(); 
         suggestions.addAll(autocomplete.suggestions); 

         String[] columns = { 
           BaseColumns._ID, 
           SearchManager.SUGGEST_COLUMN_TEXT_1, 
           SearchManager.SUGGEST_COLUMN_INTENT_DATA 
         }; 

         MatrixCursor cursor = new MatrixCursor(columns); 

         for (int i = 0; i < autocomplete.suggestions.size(); i++) { 
          String[] tmp = {Integer.toString(i), autocomplete.suggestions.get(i), autocomplete.suggestions.get(i)}; 
          cursor.addRow(tmp); 
         } 
         suggestionAdapter.swapCursor(cursor); 
        } 

        @Override 
        public void failure(RetrofitError error) { 
         Toast.makeText(SearchFoodActivity.this, error.getMessage(), Toast.LENGTH_SHORT).show(); 
         Log.w("autocompleteService", error.getMessage()); 
        } 
       }); 
       return false; 
      } 
     }); 

     return true; 
} 
+2

क्या आप कृपया अपने कार्यान्वयन को बेहतर तरीके से समझा सकते हैं? पसंद है, विधि क्या करें (सुझाव .get (स्थिति)) 'क्या करता है? धन्यवाद –

संबंधित मुद्दे