2010-03-01 10 views
11

पर काम नहीं कर रहा है मेरे पास एक AutoCompleteTextView (textView) घटक से जुड़ा एक ArrayAdapter (myAdapter) है।
एक बार जब उपयोगकर्ता एक चरित्र दबाता है तो मैं इस चरित्र वाले आइटमों के साथ AutoCompleteTextView की ड्रॉप डाउन सूची पॉप्युलेट करना चाहता हूं।
मैं AsyncTask (जो एक वेब सेवा का उपयोग करता है) का उपयोग कर आइटम पुनर्प्राप्त करता हूं।एंड्रॉइड, ऐरेएडाप्टर का() फ़ंक्शन

मैं myAdapter.add (आइटम) को कॉल करता हूं लेकिन ड्रॉप डाउन सूची खाली है।
मैंने प्रत्येक अतिरिक्त के बाद myAdapter.getCount() को कॉल किया और यह हर बार शून्य दिखाता है। कॉलिंग अधिसूचना DataSetChanged() मदद नहीं की।
मैंने अपनी कस्टम ऑब्जेक्ट्स के बजाय सरल स्ट्रिंग ऑब्जेक्ट्स जोड़ने का भी प्रयास नहीं किया, इसका कोई फायदा नहीं हुआ।
मैं क्या गलत कर रहा हूँ?

संपादित करें: मैंने कोड को नीचे दिए गए miette के रूप में बदल दिया है लेकिन अभी भी इसका कोई फायदा नहीं हुआ है।
आम तौर पर, मेरे ऑटो पूर्ण टेक्स्ट व्यू में टेक्स्ट बदलने के बाद मैं क्या करता हूं, मैं एक नया AsyncTask कॉल करता हूं और इसे दर्ज टेक्स्ट और हैंडलर पास करता हूं (बाद में टेक्स्ट चेंज() देखें)। कार्य टेक्स्ट से प्रासंगिक वस्तुओं को पुनर्प्राप्त करता है और एक बार हैंडलर के हैंडल मैसेज() को कॉल किया जाता है। हैंडल मैसेज() में मैं एडाप्टर की ऑब्जेक्ट्स को पॉप्युलेट करने का प्रयास करता हूं। लेकिन फिर भी एडाप्टर की ड्रॉप डाउन सूची खाली हो जाती है।

public class AddStockView extends Activity 
     implements OnClickListener, OnItemClickListener, TextWatcher { 

    ArrayAdapter<Stock> adapter; 
    AutoCompleteTextView textView; 
    Vector<Stock> stocks; 
    public AddStockView() { 
     // TODO Auto-generated constructor stub 
     stocks = new Vector<Stock>(); 
    } 

    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     setContentView(R.layout.add_stock_view); 

     findViewById(R.id.abort_button).setOnClickListener(this); 

     adapter = new ArrayAdapter<Stock>(this, 
     android.R.layout.simple_dropdown_item_1line, stocks); 
     //adapter.setNotifyOnChange(true); 
     textView = (AutoCompleteTextView) 
     findViewById(R.id.search_edit_text); 
     textView.setAdapter(adapter); 
     textView.setOnItemClickListener(this); 
     textView.addTextChangedListener(this); 

    } 
    @Override 
    public void onClick(View v) { 
     // TODO Auto-generated method stub 
     switch (v.getId()) 
     { 
     case R.id.abort_button: 
     finish(); 
     break; 
     case R.id.search_edit_text: 

     break; 
     } 
    } 
    @Override 
    public void onItemClick(AdapterView<?> parent, View v, 
          int position, long id) { 
     // TODO Auto-generated method stub 
     Stock stockToAdd = (Stock)parent.getAdapter().getItem(position); 
     //TODO: Add the above stock to user's stocks and close this screen 
     finish(); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     super.onCreateOptionsMenu(menu); 
     getMenuInflater().inflate(R.layout.menu, menu); 

     CategoryMenu.getInstance().populateMenu(menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     CategoryMenu.getInstance().menuItemSelected(item, this); 
     return false; 
    } 

    @Override 
    public boolean onPrepareOptionsMenu(Menu menu) { 
     return true; 
    } 
    @Override 
    public void afterTextChanged(Editable text) { 
     // TODO Auto-generated method stub 
     if (text.toString().equals("")) 
     return; 
     new AppTask().execute(new AppTask.Payload(Consts.taskType.SEARCH_STOCK, 
              new Object[] {text, handler}, this)); 

    } 
    @Override 
    public void beforeTextChanged(CharSequence a0, int a1, int a2, int a3) { 
     // TODO Auto-generated method stub 
    } 
    @Override 
    public void onTextChanged(CharSequence a0, int a1, int a2, int a3) { 
     // TODO Auto-generated method stub 
    } 
    private void addStockItemsToAdapter(Vector<Object> dataItems) 
    { 
     for (int i = 0; i <dataItems.size(); i++) 
     { 
     Stock stk = (Stock)dataItems.elementAt(i); 
     stocks.add(stk); 
     } 
    } 

    public void populateAdapter() 
    { 
     addStockItemsToAdapter(ContentReader.getInstance.getDataItems());  
     adapter.notifyDataSetChanged(); 
     int size = adapter.getCount(); // size == 0 STILL!!!! 
     textView.showDropDown(); 
    } 
    final Handler handler = new Handler() { 
     public void handleMessage(Message msg) { 
     populateAdapter(); 
     } 
    }; 
} 

धन्यवाद एक बहुत रोब

उत्तर

0

आप कहाँ कहते हैं addItemsToAdapter(),:

यहाँ मेरी कोड है? क्या आप हमें दिखा सकते हैं कि आपने अपने एडाप्टर में सरल स्ट्रिंग जोड़ने की कोशिश की है?

संपादित करें:

adapter = new ArrayAdapter<Stock>(this, android.R.layout.simple_dropdown_item_1line, stocks); 
adapter.notifyDataSetChanged(); 
textView.setAdapter(adapter); 
+0

यहाँ मैं क्या किया है: मैं एक हैंडलर परिभाषित और यह बहुत की तरह मेरे AsyncTask (AppTask कहा जाता है) में डाल पैरामीटर: फिर() new AppTask().execute(new AppTask.Payload(Consts.taskType.SEARCH_STOCK, \t \t \t \t new Object[] {text, handler}, this)); , मेरे हैंडलर के handleMessage में मैं addItemsToAdapter बुलाया । स्ट्रिंग्स के लिए, मैंने इस सरणी को घोषित किया: निजी स्थिर अंतिम स्ट्रिंग [] COUNTRIES = नया स्ट्रिंग [] { "बेल्जियम", "फ्रांस", "इटली", "जर्मनी", "स्पेन" }; और कॉल करने के बजाय: myAdapter.add (tmpItem); मैंने फोन किया; myAdapter.add (COUNTRIES [i]) और यहां तक ​​कि COUNTRIES [0]। आपकी मदद के लिए धन्यवाद! – Rob

+0

क्या कोई तरीका है कि मैं पूरा कोड पोस्ट कर सकता हूं? – Rob

+0

आप कहीं भी एक साधारण परियोजना ज़िप अपलोड कर सकते हैं या ऊपर अपना प्रश्न संपादित कर सकते हैं और कोड जोड़ सकते हैं ... – WarrenFaith

2

एक वेक्टर या जैसी सरणी के साथ एक सरणी एडाप्टर बनाएँ:: टिप्पणियाँ उपयोगी कोड नमूना से बाहर

ArrayAdapter(Context context, int textViewResourceId, T[] objects) 

अपने arrayadapter आरंभ करके, आप इसे सुन कर देगा वस्तुओं सरणी के लिए। एडाप्टर में आइटम न जोड़ें या एडाप्टर को साफ़ न करें, "ऑब्जेक्ट्स" सरणी में अपने जोड़ों को करें और इसे साफ़ करें। इस सरणी पर परिवर्तन के बाद फोन

adapter.notifyDataSetChanged(); 

अधिक विशेष रूप से

ArrayAdapter<YourContentType> yourAdapter = new ArrayAdapter<YourContentType> (this,R.id.OneOfYourTextViews,YourDataList); 

yourAdapter.notifyDataSetChanged();  
aTextView.setText(yourAdapter.isEmpty() ? "List is empty" : "I have too many objects:)"); 

यह YourDataList लोड करने के बाद किया जाना चाहिए, मैं अपने कोड की जाँच की, क्या आप वाकई हैंडलर कॉल addStockItemsToAdapter() इससे पहले कि आप देखने के लिए अपने एडाप्टर खाली है या नहीं कर रहे हैं ? आपको यह भी जांचना चाहिए कि स्टॉक वेक्टर में कोई तत्व है या नहीं।

+0

जैसा आपने सुझाव दिया था, लेकिन यह अभी भी काम नहीं करता है। मेरे पास एक हैंडलर है जिसका हैंडल मैसेज() को डेटा संरचना आने के बाद बुलाया जाता है। हैंडल मैसेज() में मैं एक फ़ंक्शन को कॉल करता हूं जो डेटा संरचना के माध्यम से पुनरावृत्ति करता है और एडाप्टर की टी [] ऑब्जेक्ट्स में तत्व जोड़ता है और फिर adapter.notifyDataSetChanged() को कॉल करता है। इस सब एडाप्टर के बाद .getCount() अभी भी शून्य लौटाता है। यह क्या हो सकता है? – Rob

+0

हाय फिर से, मैं आपके लिए अपना जवाब बदल रहा हूं। मैंने परीक्षण किया है कि आप क्या करना चाहते हैं और यह मेरे लिए काम करता है। – miette

+0

हाय मीट, मैं आपको इसकी सराहना करता हूं। आप वॉरेन के समान सुझाव दे रहे हैं और वास्तव में इस समस्या को हल किया है। बीटीडब्ल्यू, मुझे एहसास है कि कॉलिंग को सूचित करनाडेटाट चेंज() अब अनावश्यक है क्योंकि "नया ऐरे एडाप्टर" कथन में अद्यतन डेटा स्रोत शामिल है। मैंने सोचा कि मेरे एडाप्टर के निर्माण पर मेरा डेटा स्रोत (YourDataList) खाली हो सकता है, रास्ते में आइटम जोड़ें और कॉलटाइडेट चेंज() को सूचित करते समय सूचित करें, लेकिन ऐसा लगता है कि यह काम नहीं करता है, है ना? वैसे भी, मेरे आदमी को बहुत बाध्य किया। – Rob

12

मुझे एक ही समस्या थी। ArrayAdapter और AutoCompleteTextView स्रोत कोड परीक्षण करने के बाद, मुझे पता चला समस्या यह थी कि, संक्षेप में, कि:

  • मूल वस्तु सूची ArrayAdapter.mObjects में संग्रहित है।
  • हालांकि, AutoCompleteTextViewArrayAdapter फ़िल्टरिंग को सक्षम बनाता है, जिसका अर्थ है कि नई वस्तुओं को ArrayAdapter.mOriginalValues में जोड़ा गया है, जबकि mObjects में फ़िल्टर की गई वस्तुएं हैं।
  • ArrayAdapter.getCount() हमेशा mObjects का आकार देता है।

मेरा समाधान गैर फ़िल्टरिंग फ़िल्टर को वापस करने के लिए ArrayAdapter.getFilter() को ओवरराइड करना था। इस तरह null और mObjects सभी मामलों में उपयोग किया जाता है।

नमूना कोड:

public class MyAdapter extends ArrayAdapter<String> { 
    NoFilter noFilter; 
    /* 
    ... 
    */ 

    /** 
    * Override ArrayAdapter.getFilter() to return our own filtering. 
    */ 
    public Filter getFilter() { 
     if (noFilter == null) { 
      noFilter = new NoFilter(); 
     } 
     return noFilter; 
    } 

    /** 
    * Class which does not perform any filtering. 
    * Filtering is already done by the web service when asking for the list, 
    * so there is no need to do any more as well. 
    * This way, ArrayAdapter.mOriginalValues is not used when calling e.g. 
    * ArrayAdapter.add(), but instead ArrayAdapter.mObjects is updated directly 
    * and methods like getCount() return the expected result. 
    */ 
    private class NoFilter extends Filter { 
     protected FilterResults performFiltering(CharSequence prefix) { 
      return new FilterResults(); 
     } 

     protected void publishResults(CharSequence constraint, 
             FilterResults results) { 
      // Do nothing 
     } 
    } 
} 
+0

आप बहुत अच्छे हैं !!! अन्य मामलों में – Anderson

+0

फ़िल्टरिंग वह है जो आपको वास्तव में चाहिए और आप इसे [यहां] (http://android.foxykeep.com/dev/how-to-add-autocompletion-to-an-edittext) के रूप में समझा सकते हैं वेबसाइट सेवा उदाहरण। – vfede

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