问题
I'm trying to instantiate a fragment "sending" a custom object array list, but I can't find the exact way to do it. I think I may have to use Serializable
or Parcelable
(as seen in another answer), but I'm not sure how to implement it even after reading that answer.
Can someone help me? Thanks in advance.
Code to instantiate
Fragment f = new Fragment();
ArrayList<IconsCategory> category = Utils.getCategory();
ArrayList<IconItem> icons = category.getIconsArray();
f = IconsFragment.newInstance(icons);
return f;
Code in fragment to create the instance:
I know args.putArrayList()
method doesn't exist, I just wrote it to show how I expect to be able to code it.
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 class:
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 class:
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;
}
}
回答1:
You should avoid using Serializable, implementing Parcelable is is the preferred route on 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;
}
回答2:
Implement Serializable in IconItem class:
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;
}
}
then
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 implements Serializable by default so you only need to implement it in your classes.
回答3:
The other option would be to create a Listener interface, then simply "listen" for the latest list in the Fragment
in onCreate
, onResume
, etc.
Here is an example of my implementation, let me know if you need help seeing the pieces: https://goo.gl/gNJFTV
Notice the implementation of GetLogListener
found in MainActivity
and DailyViewFragment
回答4:
This will create your new Fragment and allow you to pass in the ArrayList when you create the Fragment. With this you do not have to make everything Parcelable. If you want to be able to pass you POJOs back and forth then use the Parcelable as Serializable is not a helpful as you get more complicated POJO structures. Also Parcelable has better performance.
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;
}
}
}
来源:https://stackoverflow.com/questions/35247641/instantiate-a-fragment-with-a-custom-object-array-list