web-dev-qa-db-fra.com

Ajouter dynamiquement des éléments à la vue de liste à l'aide d'un adaptateur personnalisé pour l'application Android

Donc, en ce moment, j'ai une classe d'adaptateur personnalisée qui prend un tableau d'emplacements et les ajoute à un ListView. C'est très bien et dandy, mais je voudrais ajouter des emplacements à cette liste après cette initialisation. Par exemple, quelqu'un peut "ajouter un emplacement" et l'ajoutera à cette ListView. Voici mon activité principale:

package com.example.listviewtest;

import Android.app.Activity;
import Android.os.Bundle;
import Android.view.View;
import Android.widget.ListView;

public class MainActivity extends Activity {

private ListView listView1;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Location location_data[] = new Location[]
    {
        new Location(R.drawable.ic_launcher, "Location 1", "Fruit!", "2 miles", "8-4 mon-fri\nclosed Sun"),
        new Location(R.drawable.ic_launcher, "Location 2", "Veggies!", "2 miles", "8-5"),
        new Location(R.drawable.ic_launcher, "Location 3", "Plants!", "2 miles", "8-5"),
        new Location(R.drawable.ic_launcher, "Location 4", "Flowers!", "2 miles", "8-5"),
        new Location(R.drawable.ic_launcher, "Location 5", "Baked Goods!", "2 miles", "8-5")
    };

   LocationAdapter adapter = new LocationAdapter(this, 
            R.layout.listview_item_row, location_data);

   //adapter.add(new Location(R.drawable.ic_launcher, "Location 6", "Veggies!", "2 miles", "8-5"));


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

    View header = (View)getLayoutInflater().inflate(R.layout.listview_header_row, null);
    listView1.addHeaderView(header);

    listView1.setAdapter(adapter);
}
}

Cela marche. Je veux maintenant faire quelque chose comme adapter.add(new Location(R.drawable.ic_launcher, "Location 6", "Veggies!", "2 miles", "8-5")); APRÈS l'avoir rempli avec le tableau.

Voici ma classe LocationAdapter:

package com.example.listviewtest;

import Android.app.Activity;
import Android.content.Context;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.ArrayAdapter;
import Android.widget.ImageView;
import Android.widget.TextView;

public class LocationAdapter extends ArrayAdapter<Location>{

Context context; 
int layoutResourceId;    
Location data[] = null;

public LocationAdapter(Context context, int layoutResourceId, Location[] data) {
    super(context, layoutResourceId, data);
    this.layoutResourceId = layoutResourceId;
    this.context = context;
    this.data = data;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;
    LocationHolder holder = null;

    if(row == null)
    {
        LayoutInflater inflater = ((Activity)context).getLayoutInflater();
        row = inflater.inflate(layoutResourceId, parent, false);

        holder = new LocationHolder();
        holder.imgIcon = (ImageView)row.findViewById(R.id.imgIcon);
        holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);
        holder.details = (TextView)row.findViewById(R.id.details);
        holder.distance = (TextView)row.findViewById(R.id.distance);
        holder.hours = (TextView)row.findViewById(R.id.hours);

        row.setTag(holder);
    }
    else
    {
        holder = (LocationHolder)row.getTag();
    }

    Location location = data[position];
    holder.txtTitle.setText(location.title);
    holder.imgIcon.setImageResource(location.icon);
    holder.details.setText(location.details);
    holder.distance.setText(location.distance);
    holder.hours.setText(location.hours);

    return row;
}

static class LocationHolder
{
    ImageView imgIcon;
    TextView txtTitle;
    TextView details;
    TextView distance;
    TextView hours;
}
}

Avez-vous des idées sur la façon de mettre en œuvre cela? Merci.

14
user1282637
  1. Dans votre adaptateur, changez le Locations data[] De tableau en ArrayList<Location> Et remplacez le constructeur approprié
  2. Dans votre activité, faites de votre variable data un champ (tapez ArrayList<Location>)
  3. Lorsque vous ajoutez un emplacement, vous pouvez utiliser data.add(location)
  4. Ensuite, vous pouvez appeler notifyDatasetChanged() sur votre adaptateur

Exemple de code .

8
LordRaydenMK

Stockez vos données dans un ArrayList<Location> Au lieu de simplement Location[], Puis créez une classe publique dans votre adaptateur de liste:

ArrayList<Location> data = new ArrayList<Location>();

@Override
public void add(Location location) {
    data.add(location);
    notifyDataSetChanged();
}

Ensuite, lorsque vous souhaitez ajouter un élément à la liste, il suffit d'appeler location_data.add(new_location).

Edit: Il semble que vous ayez votre choix parmi plusieurs réponses pour la plupart identiques.

3
Engineero

Il semble que vous ayez besoin de remplacer la méthode add dans votre classe LocationAdapter pour ajouter l'objet à la liste interne

@Override
public void add(Location location)
{
    super.add(location);
    data.add(location);
}

Cette implémentation nécessite que vous modifiiez les données en ArrayList au lieu d'un simple tableau, sinon vous devrez coder vous-même le redimensionnement du tableau.

ArrayList<Location> data = null; // Alternatively use new ArrayList<Location>();

Si vous ne le faites pas, les données internes resteront inchangées et un appel à ajouter ne changera pas la liste. C'est mauvais car vous utilisez la variable de données pour obtenir les valeurs des vues.

2
sotrh

Dans votre activité principale, je vous recommande d'utiliser une ArrayList <Location> plutôt que Location [] pour faciliter l'ajout de nouveaux éléments Location. Ensuite, plutôt que d'avoir LocationAdapter étendre ArrayAdapter <Location>, demandez-lui d'étendre ListAdapter <Location> afin que vous puissiez lui passer votre ArrayList <Location>.

Cela dit, tout ce que vous devez faire dans votre méthode addLocation (Location l) dans votre MainActivity, est d'ajouter un élément à la structure de données Location [] ou ArrayList <Location> que vous avez transmise à votre adaptateur, puis appelez:

adapter.notifyDataSetChanged();

Notez que vous devrez faire de votre adaptateur une variable membre dans votre MainActivity pour autoriser l'accès en dehors de votre onCreate ().

1
bstar55