如何在 Android 中创建一个可打包的对象列表?
How do I make a list of objects parcelable in Android?
所以我有一个应用程序可以通过 API 在互联网上搜索艺术家,并在手头执行此搜索后显示结果列表(艺术家姓名)。我想在更改设备的方向(纵向 - 横向)时保留此列表,而不必再次执行搜索。这是一些代码:
public class MainActivityFragment extends Fragment{
public static final String ARTIST_ID = "artistId";
private final String NO_RESULTS = "No artists found. Please check your input!";
private List<Artist> artists = new ArrayList<>();
private ArtistArrayAdapter adapter;
public MainActivityFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
final SearchView searchView = (SearchView) rootView.findViewById(R.id.search_artist);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String artistName) {
SearchArtist(artistName);
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(searchView.getWindowToken(), 0);
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
ListView listView = (ListView) rootView.findViewById(android.R.id.list);
adapter = new ArtistArrayAdapter(getActivity(), R.layout.artist_list_item, artists);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Artist artist = artists.get(position);
String artistId = artist.id;
Intent detailArtist = new Intent(getActivity(), DetailActivity.class);
detailArtist.putExtra(ARTIST_ID, artistId);
startActivity(detailArtist);
}
});
return rootView;
}
所以我认为我必须使艺术家列表可打包,然后将其传递给 onSaveInstanceState 方法。但是如何使此列表可打包?
非常感谢,我希望这不会太混乱...
首先你的美工 class 必须实现 parcelable
public class Artist implements Parcelable
然后你应该覆盖方法 writeToParcel 说你想保存什么,例如:
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mSavedString);
}
创建一个构造函数来读取保存的变量:
protected Artist(Parcel in){
mSavedString = in.readString();
}
那么创作者:
public static final Parcelable.Creator<Artist> CREATOR
= new Parcelable.Creator<Artist>() {
public Artist createFromParcel(Parcel in) {
return new Artist(in);
}
public Artist[] newArray(int size) {
return new Artist[size];
}
};
最后在您的 activity 覆盖 onsavedinstance 上:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArray("AristArray", mArtistArray);
}
此外,不要忘记通过在 activity:
的 onCreate 上执行此操作来检索
if (savedInstanceState != null) {
mArtistArray= new List<Artist>(savedInstanceState.getParcelableArray("ArtistArray"));
}
Ps: 没有试过代码,所以有什么想知道的可以问,我会尽力帮助你;)
来源:http://developer.android.com/reference/android/os/Parcelable.html
希望对您有所帮助 ;)
如何修改您的艺术家 class 使其成为 Parcelabel。
public class Artist implements Parcelable {
public static final Creator<Artist> CREATOR = new Creator<Artist>() {
public Artist createFromParcel(Parcel source) {
return new Artist(source);
}
public Artist[] newArray(int size) {
return new Artist[size];
}
};
private final String name;
public Artist(String name) {
this.name = name;
}
private Artist(Parcel in) {
name = in.readString();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
}
@Override
public int describeContents() {
return 0;
}
public String getName() {
return name;
}
}
然后使用下面的方法。
protected void onSaveInstanceState(Bundle outState) {
outState.putParcelableArrayList("key_artists",artists);
}
您需要为您的艺术家数据模型实施 Parcelable 接口 class。例如
public class ArtistParcelable implements Parcelable {
public String id;
public String artistName;
public List<String> artistImageUrls = Collections.emptyList();
public ArtistParcelable(Artist artist) {
// Do the assignments here
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
//write
dest.writeString(this.id);
dest.writeString(this.artistName);
dest.writeStringList(this.artistImageUrls);
}
protected ArtistParcelable(Parcel in) {
//retrieve
this.id = in.readString();
this.artistName = in.readString();
this.artistImageUrls = in.createStringArrayList();
}
public static final Parcelable.Creator<ArtistParcelable> CREATOR = new Parcelable.Creator<ArtistParcelable>() {
public ArtistParcelable createFromParcel(Parcel source) {
return new ArtistParcelable(source);
}
public ArtistParcelable[] newArray(int size) {
return new ArtistParcelable[size];
}
};
}
在您的片段中 - 如果您有 List mArtists,那么您可以像
一样保存和检索列表
@Override
public void onSaveInstanceState(final Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArrayList(ARTISTS, (ArrayList<? extends Parcelable>) mArtists);
}
并在 onCreateView 中
if (savedInstanceState != null) {
mArtists = savedInstanceState.getParcelableArrayList(ARTISTS);
这里有一份很好的指南,您可以按照它进行操作。
https://guides.codepath.com/android/Using-Parcelable
还有一个名为 Android Parcelable Code Generator 的 IDE 插件可用,它可以为您生成所有样板代码。
还有一个名为 Parceler 的库,非常方便。它完全删除了样板。
所以我有一个应用程序可以通过 API 在互联网上搜索艺术家,并在手头执行此搜索后显示结果列表(艺术家姓名)。我想在更改设备的方向(纵向 - 横向)时保留此列表,而不必再次执行搜索。这是一些代码:
public class MainActivityFragment extends Fragment{
public static final String ARTIST_ID = "artistId";
private final String NO_RESULTS = "No artists found. Please check your input!";
private List<Artist> artists = new ArrayList<>();
private ArtistArrayAdapter adapter;
public MainActivityFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
final SearchView searchView = (SearchView) rootView.findViewById(R.id.search_artist);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String artistName) {
SearchArtist(artistName);
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(searchView.getWindowToken(), 0);
return true;
}
@Override
public boolean onQueryTextChange(String newText) {
return false;
}
});
ListView listView = (ListView) rootView.findViewById(android.R.id.list);
adapter = new ArtistArrayAdapter(getActivity(), R.layout.artist_list_item, artists);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Artist artist = artists.get(position);
String artistId = artist.id;
Intent detailArtist = new Intent(getActivity(), DetailActivity.class);
detailArtist.putExtra(ARTIST_ID, artistId);
startActivity(detailArtist);
}
});
return rootView;
}
所以我认为我必须使艺术家列表可打包,然后将其传递给 onSaveInstanceState 方法。但是如何使此列表可打包?
非常感谢,我希望这不会太混乱...
首先你的美工 class 必须实现 parcelable
public class Artist implements Parcelable
然后你应该覆盖方法 writeToParcel 说你想保存什么,例如:
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mSavedString);
}
创建一个构造函数来读取保存的变量:
protected Artist(Parcel in){
mSavedString = in.readString();
}
那么创作者:
public static final Parcelable.Creator<Artist> CREATOR
= new Parcelable.Creator<Artist>() {
public Artist createFromParcel(Parcel in) {
return new Artist(in);
}
public Artist[] newArray(int size) {
return new Artist[size];
}
};
最后在您的 activity 覆盖 onsavedinstance 上:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArray("AristArray", mArtistArray);
}
此外,不要忘记通过在 activity:
的 onCreate 上执行此操作来检索 if (savedInstanceState != null) {
mArtistArray= new List<Artist>(savedInstanceState.getParcelableArray("ArtistArray"));
}
Ps: 没有试过代码,所以有什么想知道的可以问,我会尽力帮助你;)
来源:http://developer.android.com/reference/android/os/Parcelable.html
希望对您有所帮助 ;)
如何修改您的艺术家 class 使其成为 Parcelabel。
public class Artist implements Parcelable {
public static final Creator<Artist> CREATOR = new Creator<Artist>() {
public Artist createFromParcel(Parcel source) {
return new Artist(source);
}
public Artist[] newArray(int size) {
return new Artist[size];
}
};
private final String name;
public Artist(String name) {
this.name = name;
}
private Artist(Parcel in) {
name = in.readString();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
}
@Override
public int describeContents() {
return 0;
}
public String getName() {
return name;
}
}
然后使用下面的方法。
protected void onSaveInstanceState(Bundle outState) {
outState.putParcelableArrayList("key_artists",artists);
}
您需要为您的艺术家数据模型实施 Parcelable 接口 class。例如
public class ArtistParcelable implements Parcelable {
public String id;
public String artistName;
public List<String> artistImageUrls = Collections.emptyList();
public ArtistParcelable(Artist artist) {
// Do the assignments here
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
//write
dest.writeString(this.id);
dest.writeString(this.artistName);
dest.writeStringList(this.artistImageUrls);
}
protected ArtistParcelable(Parcel in) {
//retrieve
this.id = in.readString();
this.artistName = in.readString();
this.artistImageUrls = in.createStringArrayList();
}
public static final Parcelable.Creator<ArtistParcelable> CREATOR = new Parcelable.Creator<ArtistParcelable>() {
public ArtistParcelable createFromParcel(Parcel source) {
return new ArtistParcelable(source);
}
public ArtistParcelable[] newArray(int size) {
return new ArtistParcelable[size];
}
};
}
在您的片段中 - 如果您有 List mArtists,那么您可以像
一样保存和检索列表@Override
public void onSaveInstanceState(final Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArrayList(ARTISTS, (ArrayList<? extends Parcelable>) mArtists);
}
并在 onCreateView 中
if (savedInstanceState != null) {
mArtists = savedInstanceState.getParcelableArrayList(ARTISTS);
这里有一份很好的指南,您可以按照它进行操作。 https://guides.codepath.com/android/Using-Parcelable
还有一个名为 Android Parcelable Code Generator 的 IDE 插件可用,它可以为您生成所有样板代码。
还有一个名为 Parceler 的库,非常方便。它完全删除了样板。