1

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];
        }
    };
}
sigillum_conf
  • 423
  • 3
  • 22
  • There are multiple question regarding this problem here. For example, check this one http://stackoverflow.com/questions/13305861/fool-proof-way-to-handle-fragment-on-orientation-change – Todor Kostov Nov 24 '16 at 07:15
  • @TodorKostov hi Todor and thank you for the pointer, unfortunately the options described in that article were already applied before(setting the setRetainInstance to true as well as the if statement on the saveInstance state as described in my code) and still the method won´t work. – sigillum_conf Nov 24 '16 at 07:37
  • But have you tried to override the **onSavedInstanceState()** method and save the information you need? I can't see it in your source code. – Todor Kostov Nov 24 '16 at 07:40
  • I could not get the code that happens inside onClick to be saved into the overriten onSaveInstanceState() method, spent 4 hours on that and decided to look for an alternative. How would you do it? Any code sample based on what I have inside the click listener would be amazing – sigillum_conf Nov 24 '16 at 07:49
  • Ok, but please, give some more source code like the type of **commodities**. – Todor Kostov Nov 24 '16 at 07:58

2 Answers2

3

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!

Todor Kostov
  • 1,789
  • 1
  • 13
  • 20
  • thanks for the answer! I tried a similar solution before. I will update my code above to show you the contents of the commodities instance. It is actually a class named Stops(which is parcelable) that contains an array of an actual class named commodities(which is also parcelable)) – sigillum_conf Nov 24 '16 at 18:22
  • So what is the current state of the problem? Did you mange to solve it? – Todor Kostov Nov 24 '16 at 18:27
  • still struggling trough it. As I said, I tried using a solution like the one you provided before, but as I couldn´t get it to work I moved to try and do something different. – sigillum_conf Nov 24 '16 at 19:07
  • @sigillum_conf I'm interested to see your approach regarding the problem! – Todor Kostov Nov 24 '16 at 19:18
  • 1
    Actually I found a solution to it! I just needed a simple cast inside the lines: `commodities = (Stops[] savedInstanceState.getParcelableArray(KEY))` – sigillum_conf Nov 24 '16 at 19:51
0

Put this in your Activity tag of Manifest

 android:configChanges="orientation|keyboardHidden|screenSize"

Hope that will help.

Rv Lalwani
  • 134
  • 7
  • I did think about this but it seemed a bad solution for something that could be an issue on a grander scale. +1 because it made me lol though! thanks Rv – sigillum_conf Nov 24 '16 at 21:48