web-dev-qa-db-fra.com

Android Array Adapter avec ArrayList et ListView non mis à jour lorsque la liste est modifiée

J'ai une application Android avec un écran composé d'un ListView, que j'utilise pour afficher une liste de périphériques. Ces périphériques sont maintenus dans un tableau. 

J'essaie d'utiliser ArrayAdapter pour afficher le contenu du tableau à l'écran dans une liste. 

Cela fonctionne lorsque je charge pour la première fois la classe SetupActivity . Toutefois, il est possible d’ajouter un nouveau périphérique à la méthode addDevice () , ce qui signifie que le tableau contenant les périphériques est mis à jour. 

J'utilise notifyDataSetChanged () qui est supposé mettre à jour la liste mais cela ne semble pas fonctionner. 

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
}
}

Quelqu'un peut-il voir où je me trompe?

11
Pippa Rose Smith

Pour un ArrayAdapter, notifyDataSetChanged ne fonctionne que si vous utilisez les fonctions add, insert, remove et clear sur l'adaptateur.

  1. Utilisez clear pour effacer l’adaptateur - arrayAdapter.clear()
  2. Utilisez Adapter.add et ajoutez la liste nouvellement formée - arrayAdapter.add(deviceList)
  3. Appeler notifyDataSetChanged

Alternatives:

  1. Répétez cette étape après la création de la nouvelle liste de logiciels, mais c’est redondant

    arrayAdapter = new ArrayAdapter<Device>(this, Android.R.layout.simple_list_item_1, deviceList);
    
  2. Créez votre propre classe dérivée de BaseAdapter et ListAdapter qui vous donnera plus de flexibilité. Ceci est le plus recommandé.
35
Vrashabh Irde

Bien que la réponse acceptée résolve le problème, l'explication de la raison est incorrecte et, s'agissant d'un concept important, je pensais que je tenterais de clarifier. L'explication de Slartibartfast selon laquelle notifyDataSetChanged() ne fonctionne que lorsque add, insert, remove ou clear est appelé sur l'adaptateur est incorrect. Cette explication est vraie de la méthode setNotifyOnChange(), qui, si elle est définie sur true (comme c'est le cas par défaut), appellera automatiquement notifyDataSetChanged() lorsque l'une de ces quatre actions se produit. Je pense que l'affiche a confondu les deux méthodes. notifyDatasetChanged() lui-même n'a pas ces restrictions. Il indique simplement à l'adaptateur que la liste qu'il a vue a été modifiée et que la modification apportée à la liste importe peu. Bien que je ne puisse pas voir le code source de votre createNewDeviceList(), je suppose que votre problème vient du fait que l'adaptateur faisait référence à la liste d'origine que vous avez créée, puis que vous avez créé une nouvelle liste dans createNewDeviceList(), et que l'adaptateur était toujours En pointant sur l'ancienne liste, les modifications ne sont pas visibles. La solution mentionnée par slartibartfast fonctionne car elle efface l'adaptateur et ajoute spécifiquement la liste mise à jour à cet adaptateur. Ainsi, vous n'avez pas le problème de votre adaptateur pointant au mauvais endroit. J'espère que cela aide quelqu'un!

10
Laura

votre méthode addDevice provoque une boucle sans fin. Ne pas appeler une méthode de lui-même comme vous le faites ici:

deviceList = addDevice();
0
petey