2016-11-22 2 views
0

Ich versuche, einen Address Searcher mit Geocoder-API zu erstellen, wo der Benutzer Namen von Orten eingibt und alle zugehörigen Adressen in einer Listansicht angezeigt werden.Android: Adapter außerhalb von ListView geändert Problem

Ich bekomme diese Fehlermeldung, wenn die Suche ausgeführt wird:

java.lang.IllegalStateException: Der Inhalt des Adapters hat geändert, aber Listview nicht erhalten eine Benachrichtigung. Stellen Sie sicher, dass der Inhalt Ihres Adapters nicht von einem Hintergrundthread geändert wird, sondern nur vom UInthread.

Vergewissern Sie sich, dass Ihr Adapter notifyDataSetChanged() aufruft, wenn sich der Inhalt ändert.

Dies ist meine Implementierung:

SimpleStringAdapter adapter; 
ArrayList<String> items = new ArrayList<>(); 
ListView addressList; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_search_address); 

    addressList = (ListView) findViewById(R.id.addressList); 
    addressBox = (EditText) findViewById(R.id.addressBox); 

    //Search for locations when the user types in 
    addressBox.addTextChangedListener(new TextWatcher() { 
      @Override 
      public void onTextChanged(final CharSequence s, int start, int before, int count) { 
       //Search the typed location 
       SearchAddresses(searchText); 
      } 

      @Override 
      public void beforeTextChanged(CharSequence s, int start, int count, 
              int after) { 

      } 

      @Override 
      public void afterTextChanged(Editable s) { 

      } 
    }); 
} 

private void SearchAddresses(String searchText) { 
    Geocoder geoCoder = new Geocoder(this, Locale.getDefault()); 
    try { 
     List<Address> addresses = geoCoder.getFromLocationName(searchText, 5); 
     addressList.setAdapter(null); 

     if (addresses.size() != 0) { 
      //Add the Address line to the list 
      items.add(addresses.get(0).getAddressLine(0)); 
      //Populate the listview 
      adapter = new SimpleStringAdapter(this, items); 
      addressList.setAdapter(adapter); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

Und der Listview-Adapter einfach nur den Text in eine Textview setzt. Wenn Sie es sehen müssen, lassen Sie es mich wissen.

Was mache ich falsch?

+1

anwenden notifydatasetchanged zu Ihrem Adapter. – LoveAndroid

+0

Bitte sagen Sie mir, wo das in Bezug auf das Codebeispiel @LoveAndroid – Dinuka

+0

Ich habe ein paar Antworten gesehen, die das gleiche sagen, aber keiner von ihnen gibt an, wo ich es und irgendwelche Erklärungen hinzufügen sollte :) – Dinuka

Antwort

1

Sie Adapter jedes Mal in OnTextChanged() -Methode nicht initialisiert werden. Verwenden Sie notifyDataSetChanged(). Hier ist ein Beispiel mit Ihrem Code.

Ersetzen Sie einfach Ihren Code mit diesem. Das ist es.

SimpleStringAdapter adapter; 
ArrayList<String> items = new ArrayList<>(); 
ListView addressList; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_search_address); 

    addressList = (ListView) findViewById(R.id.addressList); 
    addressBox = (EditText) findViewById(R.id.addressBox); 

    adapter = new SimpleStringAdapter(this, items); 
    addressList.setAdapter(adapter); 

    //Search for locations when the user types in 
    addressBox.addTextChangedListener(new TextWatcher() { 
      @Override 
      public void onTextChanged(final CharSequence s, int start, int before, int count) { 
       //Search the typed location 
       SearchAddresses(searchText); 
      } 

      @Override 
      public void beforeTextChanged(CharSequence s, int start, int count, 
             int after) { 

      } 

      @Override 
      public void afterTextChanged(Editable s) { 

      } 
    }); 
} 

private void SearchAddresses(String searchText) { 
    Geocoder geoCoder = new Geocoder(this, Locale.getDefault()); 
    try { 
     List<Address> addresses =  geoCoder.getFromLocationName(searchText, 5); 
     addressList.setAdapter(null); 

     if (addresses.size() != 0) { 
      //Add the Address line to the list 
      items.add(addresses.get(0).getAddressLine(0)); 
      //Populate the listview 
      adapter.notifyDataSetChanged(); 

     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
+0

Dies zeigt keine Ergebnisse in der Listenansicht. Ist es richtig? – Dinuka

+0

ja es ist definitiv richtig. Es sollte funktionieren. ok ok, ich habe das Problem. Entfernen Sie diese Zeile aus SearchAddresses: addressList.setAdapter (null); und jetzt versuchen. –

+0

Das scheint zu funktionieren, aber ich habe ein kleines Problem. Es gibt eine leichte und offensichtliche Verzögerung beim Tippen. Liegt es daran, dass mehrere Anfragen an die SearchAddresses-Methode gesendet werden? – Dinuka

1

Versuchen Sie das notifyDataSetChanged an den Adapter hinzugefügt: -

private void SearchAddresses(String searchText) { 
    Geocoder geoCoder = new Geocoder(this, Locale.getDefault()); 
    try { 
     List<Address> addresses = geoCoder.getFromLocationName(searchText, 5); 
     addressList.setAdapter(null); 

     if (addresses.size() != 0) { 
      //Add the Address line to the list 
      items.add(addresses.get(0).getAddressLine(0)); 
      //Populate the listview 
      adapter = new SimpleStringAdapter(this, items); 
      addressList.setAdapter(adapter); 
      adapter.notifyDataSetChanged(); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
+0

Das funktioniert, aber ich sehe eine leichte Verzögerung. Ich denke, es ist teilweise, weil der Adapter jedes Mal initialisiert wird, wenn sich der Text ändert – Dinuka

+0

@DinukaJayasuriya Yup! Du hast recht . Es passiert, weil der Adapter jedes Mal initialisiert wird, wenn sich der Text ändert. – LoveAndroid

Verwandte Themen