【问题标题】:Instantiate a fragment with a Custom Object Array List使用自定义对象数组列表实例化片段
【发布时间】:2016-02-06 23:11:03
【问题描述】:

我正在尝试实例化一个“发送”自定义对象数组列表的片段,但我找不到确切的方法。我想我可能不得不使用SerializableParcelable(如另一个答案所示),但即使在阅读了该答案后我也不确定如何实现它。

有人可以帮助我吗?提前致谢。

实例化代码

Fragment f = new Fragment();

ArrayList<IconsCategory> category = Utils.getCategory();
ArrayList<IconItem> icons = category.getIconsArray();

f = IconsFragment.newInstance(icons);

return f;

片段中用于创建实例的代码: 我知道args.putArrayList() 方法不存在,我只是写它来展示我希望如何编写它。

public static IconsFragment newInstance(ArrayList<IconItem> list) {
    IconsFragment fragment = new IconsFragment();
    Bundle args = new Bundle();
    args.putArrayList(list);   // here's where the code is supposed to go 
    fragment.setArguments(args);
    return fragment;
}

IconsCategory 类:

import java.util.ArrayList;

public class IconsCategory {

    private String name;
    private ArrayList<IconItem> iconsArray = new ArrayList<>();

    public IconsCategory(String name, ArrayList<IconItem> iconsArray) {
        this.name = name;
        this.iconsArray = iconsArray;
    }

    public String getCategoryName() {
        return this.name;
    }

    public ArrayList<IconItem> getIconsArray() {
        return iconsArray.size() > 0 ? this.iconsArray : null;
    }

}

IconItem 类:

public class IconItem {

    private String name;
    private int resId;

    public IconItem(String name, int resId){
        this.name = name;
        this.resId = resId;
    }

    public String getName(){
        return this.name;
    }

    public int getResId(){
        return this.resId;
    }

}

【问题讨论】:

    标签: java android android-fragments arraylist instance


    【解决方案1】:

    您应该避免使用 Serializable,实现 Parcelable 是 Android 上的首选路线 (http://developer.android.com/reference/android/os/Parcelable.html):

    IconItem.java

    import android.os.Parcel;
    import android.os.Parcelable;
    
    public class IconItem implements Parcelable {
    
        private String name;
        private int resId;
    
        public IconItem(String name, int resId) {
            this.name = name;
            this.resId = resId;
        }
    
        public String getName() {
            return this.name;
        }
    
        public int getResId() {
            return this.resId;
        }
    
        @Override public int describeContents() {
            return 0;
        }
    
        @Override public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(name);
            dest.writeInt(resId);
        }
    
        public static final Creator<IconItem> CREATOR = new Creator<IconItem>() {
            @Override
            public IconItem createFromParcel(Parcel in) {
                String name = in.readString();
                int redId = in.readInt();
                return new IconItem(name, redId);
            }
    
            @Override
            public IconItem[] newArray(int size) {
                return new IconItem[size];
            }
        };
    }
    

    IconsCategory.java

    import android.os.Parcel;
    import android.os.Parcelable;
    
    import java.util.ArrayList;
    
    public class IconsCategory implements Parcelable {
    
        private String name;
        private ArrayList<IconItem> iconsArray = new ArrayList<>();
    
        public IconsCategory(String name, ArrayList<IconItem> iconsArray) {
            this.name = name;
            this.iconsArray = iconsArray;
        }
    
    
        public static final Creator<IconsCategory> CREATOR = new Creator<IconsCategory>() {
            @Override
            public IconsCategory createFromParcel(Parcel in) {
                String name = in.readString();
                ArrayList<IconItem> icons = new ArrayList<>();
                in.readTypedList(icons, IconItem.CREATOR);
                return new IconsCategory(name, icons);
            }
    
            @Override
            public IconsCategory[] newArray(int size) {
                return new IconsCategory[size];
            }
        };
    
        public String getCategoryName() {
            return this.name;
        }
    
        public ArrayList<IconItem> getIconsArray() {
            return iconsArray.size() > 0 ? this.iconsArray : null;
        }
    
        @Override public int describeContents() {
            return 0;
        }
    
        @Override public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(name);
            dest.writeTypedList(iconsArray);
        }
    }
    

    IconsFragment.java

    public static IconsFragment newInstance(IconsCategory category) {
        IconsFragment fragment = new IconsFragment();
        Bundle args = new Bundle();
        args.putParcelable("category", category); 
        fragment.setArguments(args);
        return fragment;
    }
    

    【讨论】:

    • 但是这会发送一个 IconCategory 到片段,我需要发送一个 ArrayList 我怎么能用 parcelable 来做呢?
    • 正确查看IconsCategory 类。此类包含 ListIconItem,您可以通过 IconCategory.getIconsArray() 获得。
    【解决方案2】:

    在 IconItem 类中实现 Serializable:

    import java.io.Serializable;
    
    public class IconItem implements Serializable {
    
        private String name;
        private int resId;
    
        public IconItem(String name, int resId){
            this.name = name;
            this.resId = resId;
        }
    
        public String getName(){
            return this.name;
        }
    
        public int getResId(){
            return this.resId;
        }
    
    }
    

    然后

    public class IconsFragment extends Fragment {
        public static final String KEY = "key";
        public static IconsFragment newInstance(ArrayList<IconItem> list) {
            IconsFragment fragment = new IconsFragment();
            Bundle args = new Bundle();
            args.putSerializable(KEY, list);
            fragment.setArguments(args);
            return fragment;
        }
    }
    

    ArrayList 默认实现 Serializable,所以你只需要在你的类中实现它。

    【讨论】:

    • 但它要求我实现 2 种方法,我不知道该放什么。
    • 谢谢。顺便说一句,现在我需要将该值分配给片段代码中的新 ArrayList 变量。 ...我正在使用 getArguments().getSerializable(KEY); ...但它说'不兼容的类型。必需:数组列表。找到:Serializable'....我现在该怎么办?
    • 尝试:list = (ArrayList) bundle.getSerializable(KEY);
    • 它没有显示错误,但显示“未经检查的演员表”。我应该担心吗?
    • 这只是警告。您可以在声明之前使用 @SuppressWarnings("unchecked") 摆脱它。
    【解决方案3】:

    另一种选择是创建一个侦听器接口,然后简单地“侦听”Fragment 中的最新列表 onCreateonResume 等。

    这是我的实现示例,如果您需要帮助,请告诉我:https://goo.gl/gNJFTV

    注意MainActivityDailyViewFragmentGetLogListener 的实现

    【讨论】:

      【解决方案4】:

      这将创建您的新 Fragment 并允许您在创建 Fragment 时传入 ArrayList。有了这个,你不必让所有东西都可以 Parcelable。如果您希望能够来回传递 POJO,那么使用 Parcelable 作为 Serializable 并没有帮助,因为您会获得更复杂的 POJO 结构。 Parcelable 也有更好的性能。

      public IconsFragment extends Fragment {
      
          private ArrayList<IconItem> list;
      
          /** Blank constructor */
          public IconsFragment() {}
      
          public static IconsFragment createFragment(@Nullable ArrayList<IconItem> list) {
              IconsFragment frag = new IconsFragment();
              frag.init(list);
              return frag;
          }
      
          public void init(ArrayList<IconItem> list) {
              if (list==null) {
                  this.list = new ArrayList<>(0);
              } else {
                  // This creates a new list coping your values into the new array
                  this.list = new ArrayList<>(list);
                  // Or this just uses your current list.
                  // JUST PICK ON OR THE OTHER.
                  this.list = list;
              }
          }
      }
      

      【讨论】:

      • 这可能在第一次在正常流程上创建片段时起作用。但是一旦操作系统需要重新创建片段(应用程序进入后台并稍后返回),它将使用默认(无参数)构造函数并且不会调用您定义的“createFragment”方法。这就是为什么使用 Bundle 很重要,Android 将使用它来重新创建片段
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-06
      • 2011-07-02
      • 2013-03-02
      相关资源
      最近更新 更多