webentwicklung-frage-antwort-db.com.de

Android Array Adapter mit ArrayList und ListView wird nicht aktualisiert, wenn die Arrayliste geändert wird

Ich habe eine Android-App mit einem Bildschirm, der aus einer ListView besteht, die ich zum Anzeigen einer Liste von Geräten verwende. Diese Geräte werden in einem Array gehalten. 

Ich versuche, den ArrayAdapter zu verwenden, um das Array auf dem Bildschirm in einer Liste anzuzeigen. 

Es funktioniert, wenn ich die SetupActivity -Klasse zum ersten Mal lade. Es besteht jedoch die Möglichkeit, ein neues Gerät in die addDevice () - Methode einzufügen, was bedeutet, dass das Array mit den Geräten aktualisiert wird. 

Ich verwende notifyDataSetChanged () , das die Liste aktualisieren soll, aber es scheint nicht zu funktionieren. 

public class SetupActivity extends Activity
{   
    private ArrayList<Device> deviceList;

    private ArrayAdapter<Device> arrayAdapter;

    private ListView listView;

    private DevicesAdapter devicesAdapter;

    private Context context;

    public void onCreate(Bundle savedInstanceState)  //Method run when the activity is created
    {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.setup);  //Set the layout

        context = getApplicationContext();  //Get the screen

        listView = (ListView)findViewById(R.id.listView);

        deviceList = new ArrayList<Device>();

        deviceList = populateDeviceList();  //Get all the devices into the list

        arrayAdapter = new ArrayAdapter<Device>(this, Android.R.layout.simple_list_item_1, deviceList);

        listView.setAdapter(arrayAdapter);  
    }

    protected void addDevice()  //Add device Method (Simplified)
    {
        deviceList = createNewDeviceList();    //Add device to the list and returns an updated list

        arrayAdapter.notifyDataSetChanged();    //Update the list
}
}

Kann jemand sehen, wo ich falsch liege?

11

Für einen ArrayAdapter funktioniert notifyDataSetChanged nur, wenn Sie die Funktionen add, insert, remove und clear des Adapters verwenden.

  1. Verwenden Sie clear, um den Adapter zu löschen - arrayAdapter.clear()
  2. Verwenden Sie Adapter.add und fügen Sie die neu gebildete Liste hinzu - arrayAdapter.add(deviceList)
  3. Rufen Sie notifyDataSetChanged auf

Alternativen:

  1. Wiederholen Sie diesen Schritt, nachdem eine neue Geräteliste erstellt wurde. Dies ist jedoch __ redundant

    arrayAdapter = new ArrayAdapter<Device>(this, Android.R.layout.simple_list_item_1, deviceList);
    
  2. Erstellen Sie Ihre eigene aus BaseAdapter und ListAdapter abgeleitete Klasse, die Ihnen mehr Flexibilität bietet. Dies wird am meisten empfohlen.
35
Vrashabh Irde

Während die akzeptierte Antwort das Problem löst, ist die Erklärung des Grundes falsch, und da dies ein wichtiges Konzept ist, dachte ich, ich würde versuchen zu klären. Die Erklärung von Slartibartfast, dass notifyDataSetChanged() nur funktioniert, wenn add, insert, remove oder clear für den Adapter aufgerufen wird, ist falsch. Diese Erklärung gilt für die setNotifyOnChange()-Methode. Wenn diese Option auf true gesetzt ist (standardmäßig), wird notifyDataSetChanged() automatisch aufgerufen, wenn eine dieser vier Aktionen ausgeführt wird. Ich glaube, das Plakat hat die beiden Methoden verwirrt. notifyDatasetChanged() selbst hat diese Einschränkungen nicht. Es teilt dem Adapter lediglich mit, dass sich die Liste, die er betrachtet, geändert hat, und es spielt keine Rolle, wie die Änderung an der Liste tatsächlich stattgefunden hat. Ich kann zwar den Quellcode für Ihre createNewDeviceList() nicht sehen, aber ich schätze, Ihr Problem rührte von der Tatsache her, dass Sie den Adapter auf die ursprüngliche Liste verwiesen haben, die Sie erstellt haben, und dann eine neue Liste in createNewDeviceList() erstellt haben und der Adapter noch vorhanden war auf die alte Liste zeigend, konnte sie die Änderungen nicht sehen. Die erwähnte Lösung slartibartfast funktioniert, da der Adapter gelöscht wird und die aktualisierte Liste speziell zu diesem Adapter hinzugefügt wird. So haben Sie nicht das Problem, dass Ihr Adapter auf die falsche Stelle zeigt. Hoffe das hilft jemandem!

10
Laura

ihre Methode addDevice verursacht eine Endlosschleife. Rufen Sie keine Methode aus sich selbst auf, wie Sie es hier tun:

deviceList = addDevice();
0
petey