sigillum_conf sigillum_conf - 12 days ago 6
Android Question

Retaining cardview after screen orientation

I have a fragment that makes an asynchronous call, assigns to an object variable(which took me a while to figure out) and then by clicking on a button it loads

cardviews
through adapters into the screen.

The code that I am using is:

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, final Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.fragments_stops_list, container, false);
ButterKnife.bind(this, view); // since this is a fragment the butterknife bind method should goafter the view declaration
// saved state would indicate that we are now not capable of making multiple requests. This point has been
// properly taken care of and now I can purposely move on to other things of more importance
loadButton = (Button) view.findViewById(R.id.LOAD);
if(savedInstanceState == null) {
loadButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(">==========<", extractCreate.getCreateR().getPhone());
Parcelable[] parcelable = extractCreate.getStopsR();
commodities = Arrays.copyOf(parcelable, parcelable.length, Stops[].class);
//Log.d("Commodities size check", String.valueOf(commodities.length));


StopsAdapter adapter = new StopsAdapter(commodities);
mRecyclerView.setAdapter(adapter);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity()); // sketchy on this part
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setHasFixedSize(true);
Log.d(TAG, "This is being called from the onCreate method");


}
});
}



return view;
}


The thing is, if I try to rotate the screen then the contents disappear and to make them appear again one has to click the button (of
id.LOAD
), I added a statement to check if the saveInstance state is null, that solution did not work as now when I turn the screen the
cardviews
that I load through the adapter disappear and there is no possibility of loading them again.

Ho can I preserve the state? I read about overriding the
onViewStateRestored
method but the idea does not seem promising since the contents need to be handled inside of a click listener.

Any suggestions will be greatly appreciated.

As requested, this is the code of the .

public class Stops implements Parcelable{
private String stop_id;
private String type;
private String location;
private String address;
private String city;
private String state;
private String zip;
private String from;
private String to;

private String getitem;

private Commodities[] commodities;



public Stops() {}
public String getStop_id() {
return stop_id;
}

public void setStop_id(String stop_id) {
this.stop_id = stop_id;
}

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}


public String getLocation() {
return location;
}

public void setLocation(String location) {
this.location = location;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}

public String getState() {
return state;
}

public void setState(String state) {
this.state = state;
}

public String getZip() {
return zip;
}

public void setZip(String zip) {
this.zip = zip;
}

public String getFrom() {
return from;
}

public void setFrom(String from) {
this.from = from;
}

public String getTo() {
return to;
}

public void setTo(String to) {
this.to = to;
}

public Commodities[] getCommodities() {
return commodities;
}



public void setCommodities(Commodities[] commodities) {
this.commodities = commodities;
}
/**
* The content for the actual parcelables start in here
*
* */

@Override
public int describeContents() {
return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.stop_id);
dest.writeString(this.type);
dest.writeString(this.location);
dest.writeString(this.address);
dest.writeString(this.city);
dest.writeString(this.state);
dest.writeString(this.zip);
dest.writeString(this.from);
dest.writeString(this.to);
dest.writeString(this.getitem);
dest.writeTypedArray(this.commodities, flags);
}

protected Stops(Parcel in) {
this.stop_id = in.readString();
this.type = in.readString();
this.location = in.readString();
this.address = in.readString();
this.city = in.readString();
this.state = in.readString();
this.zip = in.readString();
this.from = in.readString();
this.to = in.readString();
this.getitem = in.readString();
this.commodities = in.createTypedArray(Commodities.CREATOR);
}

public static final Parcelable.Creator<Stops> CREATOR = new Parcelable.Creator<Stops>() {
@Override
public Stops createFromParcel(Parcel source) {
return new Stops(source);
}

@Override
public Stops[] newArray(int size) {
return new Stops[size];
}
};
}

Answer

Due to the fact that your fragment is being destroyed and created again when the orientation is changed, you have to implement some logic in order to save the data you had collected before the orientation change event.

This is done by overriding the onSavedInstanceState(Bundle bundle) method. Everything you need to save is included in here. You put your data into the Bundle object and assign a key to it, in order to be able the retrieve it lately.

When the OS recreates your fragment again, it will go through the onCreateView() method again. This is the place where you must check if the savedInstanceState object is not NULL. If it's not, then it most probably contains some data which was saved before the orientation change event had occurred.

Check out the following gist.

public class SomeClass extends Activity {

  private static final String KEY = "some_key";

  commodities;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, final Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        View view = inflater.inflate(R.layout.fragments_stops_list, container, false);
        ButterKnife.bind(this, view); // since this is a fragment the butterknife bind method should goafter the view declaration
        // saved state would indicate that we are now not capable of making multiple requests. This point has been
        // properly taken care of and now I can purposely move on to other things of more importance
        loadButton = (Button) view.findViewById(R.id.LOAD);
        if(savedInstanceState == null) {
            loadButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Log.d(">==========<", extractCreate.getCreateR().getPhone());
                    Parcelable[] parcelable = extractCreate.getStopsR();
                    commodities = Arrays.copyOf(parcelable, parcelable.length, Stops[].class);
                    //Log.d("Commodities size check", String.valueOf(commodities.length));


                    StopsAdapter adapter = new StopsAdapter(commodities);
                    mRecyclerView.setAdapter(adapter);
                    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity()); // sketchy on this part
                    mRecyclerView.setLayoutManager(layoutManager);
                    mRecyclerView.setHasFixedSize(true);
                    Log.d(TAG, "This is being called from the onCreate method");


                }
            });
        } else {
          if(savedInstanceState.containsKey(KEY)) {
            commodities = savedInstanceState.getParcelable(KEY);
            // here you will pretty much repete the code from above
            // for creating an Adapter for the RecyclerView
                    StopsAdapter adapter = new StopsAdapter(commodities);
                    mRecyclerView.setAdapter(adapter);
                    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity()); // sketchy on this part
                    mRecyclerView.setLayoutManager(layoutManager);
                    mRecyclerView.setHasFixedSize(true);
          }
        }
        return view;
    }

      @Override
      public void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
         outState.putParcelable(KEY, commodities);
      }

}

In order to properly save your data your commodities class need to implement Parcelable. Check this link for more info. Parcelable

P.S. Due to the fact that I don't know the actual type of yout commodities object you will have to fix the code a bit. Just a simple copy -> paste won't work!