How do I create a list of objects in Android?
So I have an application that searches the internet for an artist via an API and displays a list of results (artist names) after doing this search. I want to keep this list when I change the orientation (portrait-landscape) of my device and do not need to search again. Here's some code:
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;
}
So, I think I need to make the list of artists valid and then pass it to the onSaveInstanceState method. But how do you make this list available?
Thanks a lot, I hope this is not too confusing ...
source to share
You will need to implement a Parcelable Interface for your Artist data model class. for example
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];
}
};
}
And in your snippet - if you have a list of mArtists then you save and retrieve the list like
@Override
public void onSaveInstanceState(final Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArrayList(ARTISTS, (ArrayList<? extends Parcelable>) mArtists);
}
And in onCreateView
if (savedInstanceState != null) {
mArtists = savedInstanceState.getParcelableArrayList(ARTISTS);
Here's a good guide you can follow. https://guides.codepath.com/android/Using-Parcelable
There is also an IDE plugin available called Android Parcelable Code Generator that generates all boilerplate code for you.
And there is also a library called Parceler which is very handy. It removes the template entirely.
source to share
First, your Artist class must do batch
public class Artist implements Parcelable
Then you have to override the writeToParcel method saying what you want to save, like so:
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mSavedString);
}
create a constructor to read stored variables:
protected Artist(Parcel in){
mSavedString = in.readString();
}
Then the creator:
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];
}
};
And finally, your activity overrides the onsavedinstance:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArray("AristArray", mArtistArray);
}
Also, don't forget to fetch by doing this onCreate of your activity:
if (savedInstanceState != null) {
mArtistArray= new List<Artist>(savedInstanceState.getParcelableArray("ArtistArray"));
}
Ps: haven't tried the code, so whatever you want to know will ask, I'll try and help you;)
src: http://developer.android.com/reference/android/os/Parcelable.html
Hope it helps;)
source to share
How do I change the Artist class to make it a 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;
}
}
Then use the following command.
protected void onSaveInstanceState(Bundle outState) {
outState.putParcelableArrayList("key_artists",artists);
}
source to share