2012-10-31 10 views
5

प्राप्त नहीं किया।IllegalStateException: एडाप्टर की सामग्री बदल गया है, लेकिन मैं एक ListView AutocompleteTextView पर अनुकूलक (AddressAdapter फैली ArrayAdapter) स्थापित करने के लिए एक कस्टम ArrayAdapter उपयोग कर रहा हूँ एक अधिसूचना

public class AutoCompleteAdapter extends ArrayAdapter<String> implements Filterable { 
private ArrayList<String> mData; 
ArrayList<String> listTempPrefix = new ArrayList<String>(); 
ArrayList<String> listTemp = new ArrayList<String>(); 
String valueText; 
String[] words; 
String ulcase; 

public AutoCompleteAdapter(Context context, int textViewResourceId, ArrayList<String> bS) { 
    super(context, textViewResourceId); 
    mData = bS;//new ArrayList<String>(); 
} 

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

@Override 
public String getItem(int index) 
{ 
    synchronized (listTempPrefix) 
    { 
     try { 
      //Log.e("Error", listTempPrefix.get(index)); 
      return listTempPrefix.get(index); 
     } catch(IndexOutOfBoundsException e) { 
      Log.e("Error", "IndexOutOfBoundsException"); 
      return ""; 
     } 
    } 

} 

@Override 
public Filter getFilter() 
{ 
    Filter myFilter = new Filter() { 
     @Override 
     protected FilterResults performFiltering(CharSequence constraint) 
     { 

      FilterResults filterResults = new FilterResults(); 
      synchronized (filterResults) 
      { 
       listTempPrefix.clear(); 
       listTemp.clear(); 
       //Log.e("1", "1"); 

       try { 
       if(constraint != null) { 
        // A class that queries a web API, parses the data and returns an ArrayList<Style> 
        //StyleFetcher fetcher = new StyleFetcher(); 
        //try { 
         //mData = fetcher.retrieveResults(constraint.toString()); 
        //} 
        //catch(Exception e) {} 
        // Now assign the values and count to the FilterResults object 


        for(String value: mData) { 
         valueText = value.toLowerCase(); 

         //System.out.println("constraintH - " + constraint); 

         constraint.toString().toLowerCase(); 
         ulcase = constraint.toString().toLowerCase(); 
         //System.out.println("ulcase - " + ulcase); 

         if (valueText.startsWith(ulcase)) { 
          listTempPrefix.add(value); 
         } else { 
          words = valueText.split(" "); 
          //final int wordCount = words.length; 

          // Start at index 0, in case valueText starts with space(s) 
          for (int k = 0; k < words.length; k++) { 
           if (words[k].startsWith(ulcase)) { 
            listTemp.add(value); 
            break; 
           } 
          } 
         } 

         ///listTemp.add(mData.get(i)); 
         //filterResults.count = mData.size(); 
      //   System.out.println("mData" + i + mData.get(i)); 
        } 
        //Log.e("2", "2"); 
      //  System.out.println("size " + listTemp.size() + " value" + listTemp); 

        listTempPrefix.addAll(listTemp); 

        filterResults.values = listTempPrefix; 

        filterResults.count = listTempPrefix.size(); 
        //System.out.println("size " + filterResults.count + " value" + filterResults.values); 

        //System.out.println("constraint" + constraint); 

       } 
       } catch (Exception e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
        } 
       return filterResults; 
      } 
     } 

     @Override 
     protected void publishResults(CharSequence contraint, FilterResults filterResults) 
     { 
      synchronized (filterResults) 
      { 
       if(filterResults != null && filterResults.count > 0) { 
       notifyDataSetChanged(); 
       //Log.e("notifyDataSetChanged", "notifyDataSetChanged"); 
       } 
       else { 
        notifyDataSetInvalidated(); 
        //Log.e("notifyDataSetInvalidated", "notifyDataSetInvalidated"); 
       } 
      } 
     } 
    }; 
    return myFilter; 
} 

}

मैं कभी कभी क्या मिला: नोटिस कृपया, यह वास्तव में ही होता है। लेकिन मैं इस बग से पूरी तरह से छुटकारा पाना चाहता हूं।

java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(-1, class android.widget.AutoCompleteTextView$DropDownListView) with Adapter(class com.example.test.AutoCompleteAdapter)]. 

समस्या शायद keybord से तेजी से इनपुट, विधि notifyDataSetChanged कि() issn't कॉल: यहाँ आंशिक स्टैकट्रेस है। किंतु मुझे यकीन नहीं है।

उत्तर

0

होते ही आप डाटासेट (ArrayList, Array, Cursor, आदि) के रूप में notifyDataSetChanged() विधि कॉल करना होगा अपने Adapter परिवर्तन का समर्थन। अन्यथा आप इस Exception के साथ समाप्त हो जाएंगे।

+0

के माध्यम से उन्हें वापस जाने के लिए एक स्थानीय चर का उपयोग आप कैसे IllegalStateException प्राप्त करने के लिए एक नमूना लिखा जा सका? – user1528799

7

आप performFiltering पर listTempPrefix सरणी बदल रहे हैं (स्पष्ट और addAll का प्रयोग करके), तो आप notifyDataSetChanged कॉल करने के लिए इस अपवाद से बचने के लिए की आवश्यकता होगी।

लेकिन performFiltering को ui धागे पर नहीं कहा जाता है, इसलिए notifyDataSetChanged पर कॉल अप भी अपवाद उठाएगा।

इस समस्या को हल करने का सबसे अच्छा तरीका सूची बदल रहा है publishResults के अंदर सूची टेम्पम्फिक्स सरणी, और फिर notifyDataSetChanged पर कॉल करें।

performFiltering विधि से listTempPrefix में किए गए परिवर्तनों को हटाएं (आपको अपने फ़िल्टर तर्क के आधार पर एक temp सरणी बनाने की आवश्यकता हो सकती है)।

publishResults पर, listTempPrefix सरणी को filterResults पर निहित मानों के साथ अपडेट करें, और notifyDataSetChanged पर कॉल करें।

@Override 
protected void publishResults(final CharSequence contraint, final FilterResults filterResults) { 
    listTempPrefix = (List) results.values; 
    if(filterResults != null && filterResults.count > 0) { 
     notifyDataSetChanged(); 
    } else { 
     notifyDataSetInvalidated(); 
    } 
} 

इस तरह जीयूआई धागा अद्यतन करता है जो एक पृष्ठभूमि धागा में चलाता performFiltering करने के बजाय परिणाम के लिए

@Override 
public Filter getFilter() 
{ 
    Filter myFilter = new Filter() { 
     @Override 
     protected FilterResults performFiltering(CharSequence constraint) 
     { 

      FilterResults filterResults = new FilterResults(); 
      synchronized (filterResults) 
      { 
       //listTempPrefix.clear(); // Don't change listTempPrefix here 
       ... 
         ulcase = constraint.toString().toLowerCase(); 
         //System.out.println("ulcase - " + ulcase); 

         if (valueText.startsWith(ulcase)) { 
          //listTempPrefix.add(value); // Don't change listTempPrefix 
          // To keep your logic you might need an aux array 
          // for this part 
         } else { 
          ... 
         } 

        //listTempPrefix.addAll(listTemp); // Don't change it 

        filterResults.values = listTempPrefix; // No problem here 

        filterResults.count = listTempPrefix.size(); // No problem here 
        //System.out.println("size " + filterResults.count + " value" + filterResults.values); 

        //System.out.println("constraint" + constraint); 

       } 
       } catch (Exception e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
        } 
       return filterResults; 
      } 
     } 

     @Override 
     protected void publishResults(CharSequence contraint, FilterResults filterResults) 
     { 
      // At this point, make the changes you need to listTempPrefix 
      // using filterResults.values 
      synchronized (filterResults) 
      { 
       if(filterResults != null && filterResults.count > 0) { 
       notifyDataSetChanged(); 
       //Log.e("notifyDataSetChanged", "notifyDataSetChanged"); 
       } 
       else { 
        notifyDataSetInvalidated(); 
        //Log.e("notifyDataSetInvalidated", "notifyDataSetInvalidated"); 
       } 
      } 
     } 
    }; 
    return myFilter; 
} 
+0

मुझे ज्यादा अंग्रेजी नहीं पता है। मैंने आपकी बात पूरी तरह से समझ नहीं ली, आप एक नमूना लिख ​​सकते हैं। – user1528799

+0

कुछ कोड के साथ मेरा जवाब संपादित करें, देखें कि क्या – Marcelo

+0

आपकी मदद नहीं करता है ( – user1528799

9

publishResults बदलें:

यहाँ एक उदाहरण के अपने कोड पर आधारित है।

performFiltering से निकालें listTempPrefix संदर्भ और वहाँ परिणाम की दुकान और FilterResults

+1

बिल्कुल सही जवाब, धन्यवाद! डेली कोड के साथ अवैध स्टेटस अपवाद समस्या को हल किया गया है जिसे Google ने https://developers.google.com/places/training/autocomplete-android पर स्थान स्वत: पूर्ण करने के लिए प्रदान किया है – Price

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