web-dev-qa-db-fra.com

Android ArrayList <MyObject> passer comme parcelable

Code maintenant modifié pour refléter la solution acceptée.

Cela sert maintenant d'exemple de travail pour passer un ArrayList personnalisé dans un DialogFragment.

Je passe une ArrayList d'objets personnalisés à un DialogFragment en utilisant un Bundle sur newInstance. L'arraylist est reçu correctement dans newInstance. L'appel à putParcelable s'exécute correctement (aucune erreur), mais le fait de placer des points d'arrêt dans le code parcelable dans l'objet ArrayList montre que les méthodes de parcelle ne sont pas appelées lors de la définition ou de l'obtention des données.

Suis-je en train de créer une classe LocalityList pour ArrayList et de la rendre parcelable, ou la classe Locality elle-même doit-elle être parcelable?

DialogFragment

/**
 * Create a new instance of ValidateUserEnteredLocationLocalitySelectorFragment, providing "localityList"
 * as an argument.
 */
public static ValidateUserEnteredLocationLocalitySelectorFragment newInstance(LocalityList localityList) {

    ValidateUserEnteredLocationLocalitySelectorFragment fragmentInstance = new ValidateUserEnteredLocationLocalitySelectorFragment();

    // Supply location input as an argument.
    Bundle bundle = new Bundle();
    bundle.putParcelable(KEY_LOCALITY_LIST, localityList);
    fragmentInstance.setArguments(bundle);

    return fragmentInstance;
}


/**
 * Retrieve the locality list from the bundle
 */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mLocalityList = getArguments().getParcelable(KEY_LOCALITY_LIST);
}


 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.validate_user_entered_location, container, false);

    mLocalityListView = (ListView) view.findViewById(R.id.dialogLocalityListView);
    mAdapter = new SearchLocationLocalitiesListAdapter(getActivity(), mLocalityList);
    mLocalityListView.setAdapter(mAdapter);

    return view;
}

Classe LocalityList

import Java.util.ArrayList;

import Android.os.Parcel;
import Android.os.Parcelable;

public class LocalityList extends ArrayList<Locality> implements Parcelable {

    private static final long serialVersionUID = 663585476779879096L;

    public LocalityList() {
    }

    @SuppressWarnings("unused")
    public LocalityList(Parcel in) {
        this();
        readFromParcel(in);
    }

    private void readFromParcel(Parcel in) {
        this.clear();

        // First we have to read the list size
        int size = in.readInt();

        for (int i = 0; i < size; i++) {
            Locality r = new Locality(in.readString(), in.readDouble(), in.readDouble());
            this.add(r);
        }
    }

    public int describeContents() {
        return 0;
    }

    public final Parcelable.Creator<LocalityList> CREATOR = new Parcelable.Creator<LocalityList>() {
        public LocalityList createFromParcel(Parcel in) {
            return new LocalityList(in);
        }

        public LocalityList[] newArray(int size) {
            return new LocalityList[size];
        }
    };

    public void writeToParcel(Parcel dest, int flags) {
        int size = this.size();

        // We have to write the list size, we need him recreating the list
        dest.writeInt(size);

        for (int i = 0; i < size; i++) {
            Locality r = this.get(i);

            dest.writeString(r.getDescription());
            dest.writeDouble(r.getLatitude());
            dest.writeDouble(r.getLongitude());
        }
    }
}

Classe de localité

import Android.os.Parcel;
import Android.os.Parcelable;


public class Locality implements Parcelable {

    private String mDescription;
    private double mLatitude;
    private double mLongitude;


    public Locality(String description, double latitude, double longitude) {
        super();
        this.mDescription = description;
        this.mLatitude = latitude;
        this.mLongitude = longitude;
    }

    public Locality(){
        super();
    }


    public String getDescription() {
        return mDescription;
    }

    public void setDescription(String description) {
        this.mDescription = description;
    }


    public double getLatitude() {
        return mLatitude;
    }

    public void setLatitude(double latitude) {
        this.mLatitude = latitude;
    }


    public double getLongitude() {
        return mLongitude;
    }

    public void setLongitude(double longitude) {
        this.mLongitude = longitude;
    }


    @SuppressWarnings("unused")
    public Locality(Parcel in) {
        this();
        readFromParcel(in);
    }

    private void readFromParcel(Parcel in) {
        this.mDescription = in.readString();
        this.mLatitude = in.readDouble();
        this.mLongitude = in.readDouble();
    }

    public int describeContents() {
        return 0;
    }

    public final Parcelable.Creator<Locality> CREATOR = new Parcelable.Creator<Locality>() {
        public Locality createFromParcel(Parcel in) {
            return new Locality(in);
        }

        public Locality[] newArray(int size) {
            return new Locality[size];
        }
    };


    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(mDescription);
        dest.writeDouble(mLatitude);
        dest.writeDouble(mLongitude);
    }
}
23
MartinS

Oui, créez Locality classe elle-même Parcelable, et n'oubliez pas de initialiser

ArrayList<Locality> mList= new ArrayList<Locality>();

Je sais que cette question est assez ancienne mais comme je suis venu ici à l'origine pour chercher des réponses, j'ai voulu partager mon expérience.

Oui, vous devez implémenter Parcelable pour votre classe Locality mais c'est tout.

Si votre LocalityList est UNIQUEMENT un wrapper pour ArrayList, alors vous n'en avez pas besoin.

Utilisez simplement la méthode putParcelableArrayList .

ArrayList<Locality> localities = new ArrayList<Locality>;
...
Bundle bundle = new Bundle();
bundle.putParcelableArrayList(KEY_LOCALITY_LIST, localities);
fragmentInstance.setArguments(bundle);

return fragmentInstance;

Et récupérez-le en utilisant ...

localities = savedInstanceState.getParcelableArrayList(KEY_LOCALITY_LIST);

Donc, à moins que vous n'ayez besoin de la liste de tableaux personnalisée pour une autre raison, vous pouvez éviter de faire tout ce travail supplémentaire et n'implémenter que Parcelable pour votre classe Locality.

9
Caleb