How can I restore parcelable list in android - android

I have this app that in an activity creates a list of players and displays them in a listview. When I create a player I use the populatePlayerList method and it works fine. But when I save the list in a parcel and try to restore it, it doesn't populate the listview. Can't figure out why this happens. Below is some code:
public class PlayerManager extends AppCompatActivity {
EditText playerName, playerNumber, playerPosition;
ArrayList<Player> players = new ArrayList<Player>();
ListView playerListView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player_manager);
playerName = (EditText) findViewById(R.id.etPlayerName);
playerNumber = (EditText) findViewById(R.id.etPlayerNumber);
playerPosition = (EditText) findViewById(R.id.etPlayerPosition);
playerListView = (ListView) findViewById(R.id.playerList);
if(savedInstanceState!=null){
players = savedInstanceState.getParcelableArrayList("savedList");
populatePlayerList();
}
final Button addPlayerBtn = (Button) findViewById(R.id.bAddPlayer);
addPlayerBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addPlayer(playerName.getText().toString(), playerNumber.getText().toString(), playerPosition.getText().toString());
populatePlayerList();
Toast.makeText(getApplicationContext(), playerName.getText().toString() + " added!", Toast.LENGTH_SHORT).show();
}
});
private void populatePlayerList(){
ArrayAdapter<Player> adapter = new PlayerListAdapter();
playerListView.setAdapter(adapter);
}
private void addPlayer(String name, String number, String position){
players.add(new Player(name, number, position));
}
private class PlayerListAdapter extends ArrayAdapter<Player> {
public PlayerListAdapter(){
super(PlayerManager.this, R.layout.player_list, players);
}
#Override
public View getView(int position, View view, ViewGroup parent){
if (view == null)
view = getLayoutInflater().inflate(R.layout.player_list, parent, false);
Player currentPlayer = players.get(position);
TextView name = (TextView) view.findViewById(R.id.playerName);
name.setText(currentPlayer.get_name());
TextView number = (TextView) view.findViewById(R.id.playerNumber);
number.setText(currentPlayer.get_number());
TextView playerPosition = (TextView) view.findViewById(R.id.playerPosition);
playerPosition.setText(currentPlayer.get_position());
return view;
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArrayList("savedList", players);
}
Here is my Player Class:
public class Player implements Parcelable{
private String name, position,number;
public Player (String name, String number, String position) {
this.name = name;
this.number = number;
this.position = position;
}
protected Player(Parcel in) {
name = in.readString();
position = in.readString();
number = in.readString();
}
public static final Parcelable.Creator<Player> CREATOR = new Parcelable.Creator<Player>() {
#Override
public Player createFromParcel(Parcel in) {
return new Player(in);
}
#Override
public Player[] newArray(int size) {
return new Player[size];
}
};
public String get_name() {
return name;
}
public String get_position() {
return position;
}
public String get_number(){
return number;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(position);
dest.writeString(number);
}
}
I checked the players list when i try to restore it and its empty. So i guess its never saved in outState. Any ideas why?

I fixed my problem by adding android:launchMode="singleInstance" in the PlayerManager activity in Android Manifest.xml file. And I override the onBackPressed to sent me back to a previous activity so the onDestroy method isn't called. That way I get to keep the same instance in the PlayerManager activity.

Related

cannot fetch values from firebase database

Main activity.java
public class activity_3 extends AppCompatActivity {
TextView question,option_1,option_2,option_3,description,winnner;
NumberProgressBar option_progress1, option_progress2,option_progress3;
int val_1;
int val_2;
int val_3;
DatabaseReference Polldata_3;
String optionOne;
String optionTwo;
String optionThree;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_3);
final String que = getIntent().getExtras().getString("que");
final String des = getIntent().getExtras().getString("des");
optionOne = getIntent().getExtras().getString("option1");
optionTwo = getIntent().getExtras().getString("option2");
optionThree = getIntent().getExtras().getString("option3");
final String id_user = getIntent().getExtras().getString("id");
val_1 = getIntent().getExtras().getInt("val1");
val_2 = getIntent().getExtras().getInt("val2");
val_2 = getIntent().getExtras().getInt("val3");
option_progress1 = (NumberProgressBar) findViewById(R.id.option1_progressbar);
option_progress2 = (NumberProgressBar) findViewById(R.id.option2_progressbar);
option_progress3 = (NumberProgressBar) findViewById(R.id.option3_progressbar);
Polldata_3 = FirebaseDatabase.getInstance().getReference("POll").child("poll_3");
final DatabaseReference answsersave = Polldata_3.child(id_user);
question = (TextView) findViewById(R.id.question_showpoll);
option_1 = (TextView) findViewById(R.id.option_1);
option_2 = (TextView) findViewById(R.id.option_2);
option_3 = (TextView) findViewById(R.id.option_3);
description = (TextView) findViewById(R.id.description_user_3);
winnner = (TextView) findViewById(R.id.winner);
option_1.setText(optionOne);
option_2.setText(optionTwo);
option_3.setText(optionThree);
question.setText(que);
description.setText(des);
option_progress1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
option_progress1.setProgress(val_1+1);
option_progress1.setEnabled(false);
option_progress2.setEnabled(false);
option_progress3.setEnabled(false);
val_1++;
answsersave.child("option_1_value").setValue(val_1);
//winnerdeclare();
}
});
option_progress2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
option_progress2.setProgress(val_2+1);
option_progress1.setEnabled(false);
option_progress2.setEnabled(false);
option_progress3.setEnabled(false);
val_2++;
answsersave.child("option_2_value").setValue(val_2);
// winnerdeclare();
}
});
option_progress3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
option_progress3.setProgress(val_3+1);
option_progress1.setEnabled(false);
option_progress2.setEnabled(false);
option_progress3.setEnabled(false);
val_3++;
// winnerdeclare();
answsersave.child("option_3_value").setValue(val_3);
}
});
}
}
ADAPTER CLASS
public class listview_3 extends AppCompatActivity {
ListView listviewpoll3;
private DatabaseReference Poll_data_3;
List<addpoll_3> addpoll_3List;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_listview_3);
listviewpoll3 = (ListView) findViewById(R.id.poll_listview_3);
Poll_data_3 = FirebaseDatabase.getInstance().getReference("POll").child("poll_3");
addpoll_3List = new ArrayList<>();
listviewpoll3.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> adapter, View v, int position, long id) {
Intent intent = new Intent(listview_3.this, activity_3.class);
addpoll_3 poll = addpoll_3List.get(position);
final String optionone = poll.getOption_1();
final String optiontwo = poll.getOption_2();
final String optionthree = poll.getOption_3();
final String id_user = poll.getId();
final int value_1 = poll.getOption_1_value();
final int value_2 = poll.getOption_2_value();
final int value_3 = poll.getOption_3_value();
final String question = poll.getQuestion();
final String desp = poll.getDescription();
intent.putExtra("option1",optionone);
intent.putExtra("option2",optiontwo);
intent.putExtra("option3",optionthree);
intent.putExtra("id",id_user);
intent.putExtra("val1",value_1);
intent.putExtra("val2",value_2);
intent.putExtra("val3",value_3);
intent.putExtra("que",question);
intent.putExtra("descp",desp);
startActivity(intent);
}
});
}
#Override
protected void onStart() {
super.onStart();
Poll_data_3.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
addpoll_3List.clear();
for(DataSnapshot pollSnapshot: dataSnapshot.getChildren())
{
addpoll_3 poll = pollSnapshot.getValue(addpoll_3.class);
addpoll_3List.add(poll);
}
poll_list_3 adapter = new poll_list_3(listview_3.this,addpoll_3List);
listviewpoll3.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
list class
public class poll_list_3 extends ArrayAdapter<addpoll_3> {
private Activity context;
private List<addpoll_3> addpoll_3List;
public poll_list_3(Activity context, List<addpoll_3> addpoll_3List) {
super(context, R.layout.list_layout, addpoll_3List);
this.context = context;
this.addpoll_3List = addpoll_3List;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View viewitem = inflater.inflate(R.layout.list_layout,null);
TextView textViewName = (TextView) viewitem.findViewById(R.id.tv);
TextView textViewDesp = (TextView) viewitem.findViewById(R.id.tv1);
final addpoll_3 poll1 = addpoll_3List.get(position);
textViewName.setText(poll1.getQuestion());
textViewDesp.setText(poll1.getDescription());
return viewitem;
}
}
I am making a polling app where user can create a poll which is then stored in the firebase database and retrieved into listview of the app
when the user clicks on the list view he is directed to the the activity where there are number of progressbars
i have added a ON-click listener o the progress bar, So when user clicks on the progressbar the val of that option gets incremented in the database. so when a different user vote on the same poll the value from the database is fetched and value of the current user is added displaying the winner,but problem is the value of the progressbar1 gets the value from the database but the other two keep progress bar values start from 0 every time user clicks on the other two progress bar (ie 2 and 3).
please help
addpoll_3.java
public class addpoll_3 {
String id;
String question;
String description;
String option_1;
String option_2;
String option_3;
int option_1_value;
int option_2_value;
int option_3_value;
public addpoll_3(){}
public addpoll_3(String id, String question, String description, String option_1, String option_2, String option_3, int option_1_value, int option_2_value, int option_3_value) {
this.id = id;
this.question = question;
this.description = description;
this.option_1 = option_1;
this.option_2 = option_2;
this.option_3 = option_3;
this.option_1_value = option_1_value;
this.option_2_value = option_2_value;
this.option_3_value = option_3_value;
}
public String getId() {
return id;
}
public String getQuestion() {
return question;
}
public String getDescription() {
return description;
}
public String getOption_1() {
return option_1;
}
public String getOption_2() {
return option_2;
}
public String getOption_3() {
return option_3;
}
public int getOption_1_value() {
return option_1_value;
}
public int getOption_2_value() {
return option_2_value;
}
public int getOption_3_value() {
return option_3_value;
}
}
code:
Activity_3.java
val_1 = getIntent().getExtras().getInt("val1");
val_2 = getIntent().getExtras().getInt("val2");
val_3 = getIntent().getExtras().getInt("val3");
These were changes to be made
//Read from the database
myRef.addValueEventListener(new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
String value = dataSnapshot.getValue(String.class);
Log.d(TAG, "Value is: " + value);
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w(TAG, "Failed to read value.", error.toException());
}
});

Is it possible to send an object from a fragment to another fragment?

The object that I want to send from a fragment to another fragment is "post".
The DemandFragment consist of a listview which consist of items which are post objects.
I need to send the selected item from the listview, in this case postArrayList.get(position), to SelectedPostFragment.
I've tried with bundle but this is not working...
Does someone know how to fix this?
DemandFragment:
public class DemandFragment extends Fragment {
ListView lv;
ArrayAdapter adapter;
ArrayList<Post> postArrayList;
private EditText editSearch;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_demand, container, false);
if(rootView != null){
lv = (ListView) rootView.findViewById(R.id.listDemand);
editSearch = (EditText) rootView.findViewById(R.id.search_post);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// clicked on item show post
Post selectedPost = postArrayList.get(position);
Bundle bundle = new Bundle();
bundle.putParcelable("data", (Parcelable) selectedPost);
FragmentManager fm = getActivity().getFragmentManager();
Fragment fragment = new rang.afterflight.fragments.SelectedPostFragment();
fragment.setArguments(bundle);
fm.beginTransaction().replace(R.id.content_main, fragment).commit();
}
});
}
searchPost();
return rootView;
}
public void searchPost(){
editSearch.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s);
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
ParseQuery<ParseObject> query = ParseQuery.getQuery("Post");
postArrayList = new ArrayList<Post>();
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> postList, ParseException e) {
if (e == null) {
for (ParseObject object : postList) {
Post newPost = new Post();
newPost.setAirportParse((String) object.get("airport"));
newPost.setDateParse((String) object.get("date"));
newPost.setTimeParse((String) object.get("time"));
newPost.setPersonsParse((String) object.get("persons"));
newPost.setAddressParse((String) object.get("address"));
newPost.setFlightnrParse((String) object.get("address"));
newPost.setUsername((String) object.get("username"));
newPost.setImageFile((ParseFile) object.get("profilepic"));
postArrayList.add(newPost);
}
adapter = new ListViewAdapter(getActivity(), R.layout.item_cardview, postArrayList);
lv.setAdapter(adapter);
}
}
});
}
}
SelectedPostFragment:
public class SelectedPostFragment extends Fragment {
TextView airportPost, datePost, timePost, personsPost, addressPost,
flightnrPost, postedbyPost, contactPost;
ImageView iv;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_selectedpost, container, false);
airportPost = (TextView) rootView.findViewById(R.id.airport_post);
datePost = (TextView) rootView.findViewById(R.id.date_post);
timePost = (TextView) rootView.findViewById(R.id.time_post);
personsPost = (TextView) rootView.findViewById(R.id.persons_post);
addressPost = (TextView) rootView.findViewById(R.id.address_post);
flightnrPost = (TextView) rootView.findViewById(R.id.flightnr_post);
postedbyPost = (TextView) rootView.findViewById(R.id.postedby_post);
contactPost = (TextView) rootView.findViewById(R.id.contact_post);
Post selectedPost = getArguments().getParcelable("object");
String s = (String) selectedPost.get("airport");
Log.d("AIRPORT NAME", s);
return rootView;
}
}
Post:
#ParseClassName("Post")
public class Post extends ParseObject implements Serializable {
public Post(){
super();
}
public String getId(){
return getString("objectId");
}
public void setId(String id){
put("objectId", id);
}
//////////
public String getUsername(){
return getString("username");
}
public void setUsername(String username){
put("username", username);
}
public String getAirportParse(){
return getString("airport");
}
public void setAirportParse(String airport){
put("airport", airport);
}
//////////
public String getDateParse(){
return getString("date");
}
public void setDateParse(String date){
put("date", date);
}
//////////
public String getTimeParse(){
return getString("time");
}
public void setTimeParse(String time){
put("time", time);
}
//////////
public String getPersonsParse(){
return getString("persons");
}
public void setPersonsParse(String persons){
put("persons", persons);
}
//////////
public String getAddressParse(){
return getString("address");
}
public void setAddressParse(String address){
put("address", address);
}
public String getFlightnrParse(){
return getString("flightnr");
}
public void setFlightnrParse(String flightnr){
put("flightnr", flightnr);
}
public Bitmap getImageFile(){
Bitmap bmp = null;
ParseFile image = getParseFile("profilepic");
if(image != null){
try {
byte[] data = image.getData();
bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
} catch (ParseException e) {
e.printStackTrace();
}
}
return bmp;
}
public void setImageFile(ParseFile file) {
if (file != null) {
put("profilepic", file);
}
}
}
I believe your Post class needs to implement Parcelable as well to pass it in a bundle between fragments with putParcelable().
Check out: Parcelable.
This is also a great example.
Basic implementation:
public class Post extends ParseObject implements Serializable, Parcelable {
...
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeString(getId());
out.writeSring(getUsername());
...
}
public static final Parcelable.Creator<Post> CREATOR
= new Parcelable.Creator<Post>() {
public Post createFromParcel(Parcel in) {
return new Post(in);
}
public Post[] newArray(int size) {
return new Post[size];
}
};
private Post(Parcel in) {
// Items must be read in the order they were written.
setId(in.readString());
setUsername(in.readString());
...
}
}
Try that on for size, hope it helps.
Use the activity as a transporting mechanism.
Create an interface for the activity to implement, which the activity passes to the fragment upon instantiation. Whenever you want to transfer data, call the callback for the interface. Co-ordinate with the activity which fragment it needs to interact with and then post your data in another callback that will be linked to the fragment.
If all of this is too complex, then just use Otto and enjoy sending events everywhere without having to worry about detaching/attaching interfaces/listeners upon configuration change.

How to send data using putExtra of the an Adapter Class to a new Activity

I have a problem to send data using putExtra (of the a Adapter Class to an new Activity). I think that my problem is in Parcelable, but I cannot find where there are the problem.
Follow my class for you understand better.
Consultorio.class
public class Consultorio implements Parcelable {
private String nome;
private int photo;
public Consultorio() {
}
* #param nome
* #param photo
public Consultorio( String nome, int Photo)) {
this.nome = nome;
this.photo = photo;
}
/**
* #return
*/
public String getNome() {
return nome;
}
/**
* #param nome
*/
public void setNome(String nome) {
this.nome = nome;
}
public int getPhoto() {
return photo;
}
public void setPhoto(int photo) {
this.photo = photo;
}
//PARCELABLE
public Consultorio(Parcel parcel){
setNome(parcel.readString());
setPhoto(parcel.readInt());
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(photo);
dest.writeString(nome);
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator<Consultorio>() {
#Override
public Consultorio createFromParcel(Parcel source) {
return new Consultorio(source);
}
#Override
public Consultorio[] newArray(int size) {
return new Consultorio[size];
}
};
public void readFromParcel(Parcel in) {
nome = in.readString();
photo = in.readInt();
}
}
Follow My Class Fragment (because I'm using TabLayout)
public class ClinicaMedicaFragment extends Fragment {
private List<Consultorio> consultorioList = new ArrayList<Consultorio>();
private ClinicaAdapter adapter;
private Toolbar toolbar;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v =inflater.inflate(R.layout.clinica_medica_fragment, container, false);
RecyclerView recyclerView = (RecyclerView) v.findViewById(R.id.clinica_recyclerView);
toolbar = (Toolbar) v.findViewById(R.id.tb_main);
GridLayoutManager manager = new GridLayoutManager(v.getContext(),
2, GridLayoutManager.VERTICAL, false);
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
return (position % 3 == 0 ? 2 : 1);
}
});
recyclerView.setLayoutManager(manager);
List<Consultorio> list = new ArrayList<Consultorio>();
Consultorio c0 = new Consultorio();
c0.setPhoto(R.mipmap.img1);
c0.setNome("Name 1");
Consultorio c1 = new Consultorio();
c1.setPhoto(R.mipmap.img2);
c1.setNome("Name 2");
Consultorio c2 = new Consultorio();
c2.setPhoto(R.mipmap.img3);
c2.setNome("Name 3");
list.add(c0);
list.add(c1);
list.add(c2);
consultorioList = list;
adapter = new ClinicaAdapter(list);
recyclerView.setAdapter(adapter);
return v;
}
Follow My CLASS Adapter (in this class I'm using putExtra for send datato an new Activity)
public class ClinicaAdapter extends RecyclerView.Adapter<ClinicaAdapter.ViewHolder>{
private List<Consultorio> consultorioList;
//protected Boolean isHomeList = false;
public ClinicaAdapter(List<Consultorio> data) {
consultorioList = data;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.clinica_medica_item, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final Consultorio consultorio = consultorioList.get(position);
holder.imageViewPhoto.setImageResource(consultorio.getPhoto());
holder.imageViewPhoto.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
Intent intent = new Intent(view.getContext(), ClinicaActivity.class);
intent.putExtra("consultorio", consultorio);
view.getContext().startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return consultorioList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView imageViewPhoto;
public ViewHolder(View itemView) {
super(itemView);
imageViewPhoto = (ImageView) itemView.findViewById(R.id.clinc_img);
}
}
Inmy Class Activity I pick up information by
Consultorio mConsultorio;
mConsultorio = getIntent().getParcelableExtra("consultorio");
The parcelable should maintain order of write and read members. Your writeToParcel method write int photo first and then string nome, but readFromParcel method read int photo secondly.
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(nome); // <- I changed nome firstly.
dest.writeInt(photo);
}
public void readFromParcel(Parcel in) {
nome = in.readString();
photo = in.readInt();
}
I strongly recommend you to find and install Android Pacelable Code Generator plugin in Android Studio. It will automatically generate Parcelable i/o of the class for you. After installing the plugin, just right click at the class name, and click "Generate..." > "Parcelable" menu.

How do I make a list of objects parcelable in Android?

So I have an app that searches for an artist on the internet, via an API and displays the list of the results (artist names) after performing this search at hand. I want to retain this list as I change the orientation (portrait - landscape) of my device and not having to perform the search again. Here is 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 have to make the List of artists parcelable and then pass it to the onSaveInstanceState method. But how do make this list parcelable?
Thanks a lot, I hope this isn't too confusing...
You'll need to implement the 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 fragment - if you have List 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, which you can follow.
https://guides.codepath.com/android/Using-Parcelable
There's an IDE plugin called Android Parcelable Code Generator available also, which generates all the boilerplate code for you.
And there's also a library called Parceler, which is pretty handy. It removes the boilerplate entirely.
First your Artist class must implement parcelable
public class Artist implements Parcelable
Then you should override the method writeToParcel saying what you want to save, for example:
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mSavedString);
}
create a constructor to read the saved 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 on your activity override onsavedinstance:
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArray("AristArray", mArtistArray);
}
Also, do not forget to retrive by doing this onCreate of your activity:
if (savedInstanceState != null) {
mArtistArray= new List<Artist>(savedInstanceState.getParcelableArray("ArtistArray"));
}
Ps: did not try the code, so anything you want to know ask, I will try and help you ;)
src: http://developer.android.com/reference/android/os/Parcelable.html
Hope it help ;)
How About modifying your Artist class to make it 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 following.
protected void onSaveInstanceState(Bundle outState) {
outState.putParcelableArrayList("key_artists",artists);
}

How do I populate a spinner with a list of objects and not just strings?

Hello I'm new at Android. I want to populate a Spinner with a list of objects. I have googled how to do it but I just find examples with an array of strings.
Can any one help me?
This is my code:
Categories class:
public class Categories
{
#com.google.gson.annotations.SerializedName("id")
private String mId;
#com.google.gson.annotations.SerializedName("name")
private String mName;
public Categories()
{}
public Categories(String id, String name)
{
this.setId(id);
this.setName(name);
}
#Override
public String toString()
{
return mName;
}
// ******** GET *************
public String getId()
{
return mId;
}
public String getName()
{
return mName;
}
// ******** SET *************
public final void setId(String id)
{
mId = id;
}
public final void setName(String name)
{
mName = name;
}
}
This is my Activity code:
public class AgregarActividadActivity extends ActionBarActivity
{
private MobileServiceClient mClient;
private MobileServiceTable<Activities> mActivitiesTable;
private MobileServiceTable<Categories> mCategoriesTable;
private MobileServiceTable<Projects> mProjectsTable;
private EditText mTxtTitulo;
private EditText mTxtDescr;
String categryId = null;
List<Categories> catList = new ArrayList<Categories>();
Spinner spEstado;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_agregar_actividad);
try
{
mClient = new MobileServiceClient(
"https://site.azure-mobile.net/",
"AppKey",
this);
mActivitiesTable = mClient.getTable(Activities.class);
mCategoriesTable = mClient.getTable(Categories.class);
}
catch (MalformedURLException e)
{
createAndShowDialogExc(new Exception("There was an error creating the Mobile Service. Verify the URL"), "Error");
}
mTxtTitulo = (EditText) findViewById(R.id.txtTitulo);
mTxtDescr = (EditText) findViewById(R.id.txtDescripcion);
getCategories();
spEstado = (Spinner)this.findViewById(R.id.spEstado);
ArrayAdapter<Categories> Adapter = new ArrayAdapter<Categories>(this,
android.R.layout.simple_spinner_item, catList);
Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spEstado.setAdapter(Adapter);
spEstado.setOnItemSelectedListener(
new AdapterView.OnItemSelectedListener() {
public void onItemSelected(
AdapterView<?> parent,
View view,
int position,
long id) {
Categories item = (Categories) parent.getItemAtPosition(position);
}
public void onNothingSelected(AdapterView<?> parent) {
}
}
);
spProjects = (Spinner)this.findViewById(R.id.spProyecto);
ArrayAdapter<Projects> proAdapter = new ArrayAdapter<Projects>(this,
android.R.layout.simple_spinner_item, proList);
proAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spProjects.setAdapter(proAdapter);
}
private void getCategories()
{
mCategoriesTable.execute(new TableQueryCallback<Categories>()
{
public void onCompleted(List<Categories> result, int count, Exception exception, ServiceFilterResponse response)
{
if (exception == null)
{
for (Categories item : result)
{
catList.add(item);
}
}
else
{
createAndShowDialog(exception, "Error");
}
}
});
}
}
I get the dropdownlist with the objects, but when I select one item, it is not displayed as the selected item, when the dropdownlist is hidden.
Any idea will help me! Thank you!!
You need to write a CustomAdapter for this. It is similar to writing a CustomAdapter for a ListView. You can look at Custom Adapter for List View for an idea

Categories

Resources