【问题标题】:Android ArrayList<MyObject> pass as parcelableAndroid ArrayList<MyObject> 作为 parcelable 传递
【发布时间】:2012-06-12 18:22:05
【问题描述】:

现在修改代码以反映可接受的解决方案。

现在这是一个如何将自定义 ArrayList 传递到 DialogFragment 的工作示例。

我正在使用 newInstance 上的 Bundle 将自定义对象的 ArrayList 传递给 DialogFragment。 在 newInstance 中正确接收了 arraylist。对 putParcelable 的调用执行良好(没有错误),但是在 ArrayList 对象的 parcelable 代码中放置断点表明在设置或获取数据时没有调用 parcel 方法。

我是否正确地为 ArrayList 创建了一个 LocalityList 类并使其可打包,或者 Locality 类本身应该是可打包的?

对话框片段

/**
 * 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;
}

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());
        }
    }
}

位置类

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

【问题讨论】:

    标签: android parameters parcelable


    【解决方案1】:

    我知道这个问题很老了,但由于我最初是来这里寻找答案的,所以我想分享我的经验。

    是的,您需要为您的 Locality 类实现 Parcelable,仅此而已。

    如果您的 LocalityList 只是 ArrayList 的包装器,那么您不需要它。

    只需使用putParcelableArrayList 方法。

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

    然后使用...检索它

    localities = savedInstanceState.getParcelableArrayList(KEY_LOCALITY_LIST);
    

    因此,除非您出于其他原因需要自定义 ArrayList,否则您可以避免做任何额外的工作,只为您的 Locality 类实现 Parcelable。

    【讨论】:

      【解决方案2】:

      是的,让Locality类本身Parcelable,别忘了初始化

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

      【讨论】:

      • 谢谢。 LocalityList 和 Locality 类是否都需要是可打包的,或者只是 Locality 类本身。我原以为我需要对 ArrayList 进行打包,这将序列化数组中的所有单个类。
      • 是的,您必须在两者上都实现 parcelable。并且serializable适用于Java(不推荐用于Android)总是使用parcelable。
      • 上面的代码已被修改以实施可接受的解决方案。现在如图所示正常工作。这演示了如何将自定义 ArrayList 传递到 FragmentDialog 以在 ListView 中显示。
      【解决方案3】:

      我通常使用的技巧是使用 Gson(来自 google)将列表解析为 Json。另一方面,我只是将 Json 中的字符串分回一个新列表。

      从未发现任何延迟。

      【讨论】:

      • 多一点信息总是好的(小代码示例来演示)。目前,您的回答不像是对问题的回答。
      • stackoverflow.com/questions/4318458/… 基本上这是我通常做的。列表 -> JSON 字符串;捆; JSON 字符串 -> 列表;
      猜你喜欢
      • 1970-01-01
      • 2019-07-30
      • 2017-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-10
      • 2012-11-23
      • 1970-01-01
      相关资源
      最近更新 更多