2011-11-11 10 views
27

अपडेट करना मैं एक रीस्टफुल वेब सेवा से सूची प्राप्त करके ऑटोकंपलेटटेक्स्टव्यू द्वारा दिए गए सुझावों को समय-समय पर बदलना चाहता हूं, और इसे आसानी से काम नहीं कर सकता। मैं यह काम कर रहा सुनिश्चित करने के लिए सुझावों की एक हार्ड-कोडेड सूची को सेट:डायनामिक रूप से एक ऑटोकंपलेटटेक्स्ट व्यू एडाप्टर

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list_item, new String[] {"Hi", "Ho"}); 
speciesName.setAdapter(adapter);//my autocomplete tv 

मैं TextView पर एक TextWatcher मिल गया है और जब पाठ परिवर्तन है कि एक गैर अवरुद्ध कॉल की शुरूआत सुझावों की एक नई सूची प्राप्त करने के लिए - यह हिस्सा जो एक नई सूची प्राप्त करता है ठीक काम कर रहा है। तब मैं एडाप्टर पुनर्स्थापित करने के लिए है, इसलिए की तरह हैं:

public void setOptionsAndUpdate(String[] options) { 
    Log.d(TAG, "setting options"); 
    //speciesName.setAdapter((ArrayAdapter<String>)null); 
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list_item, options); 
    speciesName.setAdapter(adapter); 
} 

इस विधि कहा जाता है, लेकिन काम नहीं करता है - सुझावों की सूची या तो गायब हो जाता है या प्रदर्शित सुझाव setAdapter करने के लिए कॉल के बावजूद अपरिवर्तित ही रहेंगे।

क्या यह भी सही दृष्टिकोण है? मैंने SimpleCursorAdapter पर देखा लेकिन सामग्री प्रदाता के रूप में मेरी वेब सेवा को पंजीकृत करने का तरीका नहीं देख सका। (यह रूप http://www.blah.com/query?term=XX, जहां XX मेरे ऐप्स से इनपुट है की है, और प्रतिक्रिया तार के एक JSON सरणी है।)

+0

मैं यहां कुछ ऐसा कर रहा हूं !!! http://stackoverflow.com/questions/12854336/autocompletetextview-backed-by-cursorloader – toobsco42

उत्तर

14

यह कैसे मैं अपने AutoCompleteTextView अद्यतन है: निश्चित रूप से अब

String[] data = terms.toArray(new String[terms.size()]); // terms is a List<String> 
ArrayAdapter<?> adapter = new ArrayAdapter<Object>(activity, android.R.layout.simple_dropdown_item_1line, data); 
keywordField.setAdapter(adapter); // keywordField is a AutoCompleteTextView 
if(terms.size() < 40) keywordField.setThreshold(1); 
else keywordField.setThreshold(2); 

, इस स्थिर है और एक से अधिक हवा सुझाव के साथ सौदा नहीं करता है लेकिन, मैं यह भी सुझाव कर सकते हैं परिवर्तन के लिए एडाप्टर सूचित करने के लिए आप AutoCompleteTextView के लिए असाइन करें के बाद:

adapter.notifyDataSetChanged(); 

आशा इस मदद करता है।

-serkan

+0

बहुत बहुत धन्यवाद, यह मेरे लिए हल करता है। – jaybee

+0

@serkan: बढ़िया, यह वही है जो मुझे चाहिए। हालांकि, मुझे लगता है कि दहलीज अपडेट नहीं है, है ना? तो आपके उदाहरण में, अगर शुरुआत में 'terms.size() <40', दहलीज हमेशा के लिए 1 में रहेगी। बेशक आप अपडेट करने के लिए कोड की उस पंक्ति को फिर से चला सकते हैं। धन्यवाद! –

+0

धन्यवाद लुइस। खैर, मैं जो कर रहा हूं वह कह रहा है, अगर मेरे पास चीजों की एक छोटी सूची है, तो मैं 1 वर्ण के प्रवेश के बाद भी सुझाव देना शुरू कर सकता हूं; हालांकि अगर मेरा पूल बड़ा है, तो मुझे दक्षता उद्देश्यों के लिए कुछ भी सुझाव देने के लिए मेरे लिए दो वर्ण दर्ज किए जाने तक प्रतीक्षा करनी चाहिए। आप निश्चित रूप से इसे 1, या 2 हमेशा रखते हैं। – serkanozel

18

इस विषय गूगल मानचित्र एपीआई में दूरदराज के डेटा का उपयोग कर एक AutoCompleteTextView here पॉप्युलेट करने के लिए पर एक बहुत अच्छा ट्यूटोरियल नहीं था।

यदि आपको कैश किए गए संस्करण की आवश्यकता है, तो मैंने इसे here से पुनर्प्राप्त किया। मूल ट्यूटोरियल हटा दिया गया है, लेकिन अनिवार्य रूप से आपको एक कस्टम फ़िल्टर के साथ एक ArrayAdapter को नीचे दिखाए गए तरीके से लिखने की आवश्यकता है और इसे अपने AutoCompleteTextView पर असाइन करें।

नोट: आपको एक विधि स्वत: पूर्ण() को कार्यान्वित करने की आवश्यकता है जो स्वत: पूर्णता लाने और स्वत: पूर्णता आइटम लौटने के लिए जो भी संचालन आवश्यक है। चूंकि फ़िल्टर पृष्ठभूमि थ्रेड में लगाया जाता है, यह मुख्य यूआई थ्रेड को अवरुद्ध नहीं करेगा।

private class PlacesAutoCompleteAdapter extends ArrayAdapter<String> implements Filterable { 
private ArrayList<String> resultList; 

public PlacesAutoCompleteAdapter(Context context, int textViewResourceId) { 
    super(context, textViewResourceId); 
} 

@Override 
public int getCount() { 
    return resultList.size(); 
} 

@Override 
public String getItem(int index) { 
    return resultList.get(index); 
} 

@Override 
public Filter getFilter() { 
    Filter filter = new Filter() { 
     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 
      FilterResults filterResults = new FilterResults(); 
      if (constraint != null) { 
       // Retrieve the autocomplete results. 
       resultList = autocomplete(constraint.toString()); 

       // Assign the data to the FilterResults 
       filterResults.values = resultList; 
       filterResults.count = resultList.size(); 
      } 
      return filterResults; 
     } 

     @Override 
     protected void publishResults(CharSequence constraint, FilterResults results) { 
      if (results != null && results.count > 0) { 
       notifyDataSetChanged(); 
      } 
      else { 
       notifyDataSetInvalidated(); 
      } 
     }}; 
    return filter; 
} 
} 
+0

बिल्कुल सही! वह लिंक बस मीठा मजाक कर रहा है! इसके लिए धन्यवाद्! :) – Jona

+0

यह यूआई ट्रॉइड को अवरुद्ध नहीं करता है जब यह नेटवर्क कॉल – jonney

+0

बनाता है मेरे पास यूआई थ्रेड के बारे में एक ही सवाल था। @manyobject आप clerify कर सकते हैं? –

28

मैं adapter.notifyDataSetChanged() का उपयोग करते समय गतिशील रूप से जोड़ने और अनुकूलक में डेटा को बदलने के लिए किसी भी भाग्य नहीं था। मेरी स्थिति में, मैं एक बाहरी एपीआई को असीमित रूप से मार रहा था और समय-समय पर पूरा होने वाला डेटा प्राप्त कर रहा था।

यह कोड एडाप्टर को साफ़ करता है, और जैसा कि आप उम्मीद करेंगे उतना नया डेटा जोड़ता है। हालांकि, मुझे डेटाफिल्टर() फ़िल्टर करने के लिए डेटा को मजबूर करने के लिए फ़िल्टर विधि को कॉल करना पड़ा। साथ ही, मुझे AutocompleteTextView में वर्तमान पाठ के आधार पर स्पष्ट रूप से फ़िल्टर करना पड़ा क्योंकि मेरा एपीआई कॉल असीमित था।

adapter.clear(); 
for (Map<String, String> map : completions) { 
    adapter.add(map.get("name")); 
} 

//Force the adapter to filter itself, necessary to show new data. 
//Filter based on the current text because api call is asynchronous. 
adapter.getFilter().filter(autocompleteTextView.getText(), null); 
+0

'शून्य' में गुजरने के बजाय आप 'autocompleteTextView' में इस तरह से व्यवहार कर सकते हैं कि यह 'AutoCompleteTextView.performFiltering()' करता है - पाठ को बदलने के बाद आमतौर पर कहा जाने वाला तरीका – kassim

+0

खोज करने के लिए समय व्यतीत करना इस। मैं तुम्हारी एक बियर है :) – codingpuss

+0

धन्यवाद @ जीएलई। आपने मेरा दिन बना दिया। –

2

के बाद से मैं एक टिप्पणी जोड़ने में सक्षम नहीं हूँ, मैं एक नया उत्तर दे रहा हूँ एडाप्टर समाशोधन या adapter.getFilter फोन करने के लिए कोई जरूरत नहीं है()। फ़िल्टर कर (...) ... एक ऑटोकंपलेटटेक्स्ट व्यू एडाप्टर को गतिशील रूप से अपडेट करने के लिए, बस एडाप्टर में नया आइटम जोड़ें और फिर एडाप्टर सेट करें। मूल प्रश्न में दिए गए उदाहरण के लिए, मैंने निम्नलिखित की कोशिश की और यह काम करता है (नीचे दिया गया कोड एडाप्टर की प्रारंभिक सेटिंग नहीं दिखाता है, क्योंकि यहां कई उत्तरों इसे कवर करते हैं। यह केवल एडाप्टर को गतिशील रूप से अद्यतन करता है)। एडाप्टर अपडेट उस कोड के साथ हो सकता है जो ArrayAdapter से जुड़ी सूची अद्यतन करता है।

adapter.add(String newSuggestion); // this goes inside a loop for adding multiple suggestions 
    speciesName.setAdapter(adapter) ; // speciesName is an AutoCompleteTextView as given in the original question. 
संबंधित मुद्दे