Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

onSaveInstanceState is not being called in Fragment

I know that people have asked this question, but I followed all the answers and I still have the same problem. I have two scripts One is the fragment manager (IngredientsActivity) and the other is the fragment (OtherList). The code is as follows

IngredientsActivity

import java.util.ArrayList;

import android.app.ActionBar;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;



public class IngredientsActivity extends FragmentActivity implements ActionBar.TabListener {

    private static final String STATE_SELECTED_NAVIGATION_ITEM = "selected_navigation_item";

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.check_list);

        // Set up the action bar.
        final ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        // For each of the sections in the app, add a tab to the action bar.
        actionBar.addTab(actionBar.newTab().setText("Alcahol").setTabListener(this));
        actionBar.addTab(actionBar.newTab().setText("Juice").setTabListener(this));
        actionBar.addTab(actionBar.newTab().setText("Other").setTabListener(this));
    }

    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {

        if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) {
            getActionBar().setSelectedNavigationItem(savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM));
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);          //OVERRIDE SAVE ON MAINCLASS

        outState.putInt(STATE_SELECTED_NAVIGATION_ITEM, getActionBar().getSelectedNavigationIndex());
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        return true;
    }



    @Override
    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    }

    @Override
    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {


        if (tab.getPosition() == 0) {
            AlcoholList simpleListFragment = new AlcoholList();
            getSupportFragmentManager().beginTransaction().replace(R.id.containert, simpleListFragment).commit();
        } 
        else if (tab.getPosition() == 1) {
            JuiceList androidlidt = new JuiceList();
            getSupportFragmentManager().beginTransaction().replace(R.id.containert, androidlidt).commit();
        }



        else {

            OtherList androidversionlist = new OtherList();
            getSupportFragmentManager().beginTransaction().replace(R.id.containert, androidversionlist).commit();

        }
    }

    @Override
    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    }

       public static class DummySectionFragment extends Fragment {
        public DummySectionFragment() {
        }

        public static final String ARG_SECTION_NUMBER = "section_number";

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            TextView textView = new TextView(getActivity());
            textView.setGravity(Gravity.CENTER);
            Bundle args = getArguments();
            textView.setText(Integer.toString(args.getInt(ARG_SECTION_NUMBER)));
            return textView;
        }
    }



}

OtherList

import java.util.ArrayList;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ListView;


public class OtherList  extends ListFragment{
    MyCustomAdapter dataAdapter = null;
    private  ArrayList<String> recipesList;
private ArrayList<Items> stateList ;

public OtherList() {

    setRetainInstance(true);
     stateList = new ArrayList<Items>();

          Items _states1 = new Items ("Gin",false);
          stateList.add(_states1);
Items _states2 = new Items ("Ginger Liqueur",false);
          stateList.add(_states2);
Items _states3 = new Items ("Citrus Vodka",false);
          stateList.add(_states3);
Items _states4 = new Items ("Champagne",false);
          stateList.add(_states4);
Items _states5 = new Items ("Coconut Rum",false);
          stateList.add(_states5);
Items _states6 = new Items ("Pear Vodka",false);
          stateList.add(_states6);
Items _states7 = new Items ("Rum",false);
          stateList.add(_states7);
Items _states8 = new Items ("Tequila",false);
          stateList.add(_states8);
Items _states9 = new Items ("Triple Sec",false);
          stateList.add(_states9);
Items _states10 = new Items ("Kahlua",false);
          stateList.add(_states10);

        }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


          dataAdapter = new MyCustomAdapter(this.getActivity(),R.layout.da_item, stateList);
          setListAdapter(dataAdapter);    

    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        return inflater.inflate(R.layout.list_fragment, container, false);
    }

    @Override
    public void onListItemClick(ListView list, View v, int position, long id) {


    }

    private class MyCustomAdapter extends ArrayAdapter<Items>
{

 private ArrayList<Items> stateList;

public MyCustomAdapter(Context context, int textViewResourceId, 

ArrayList<Items> stateList) 
{
      super(context, textViewResourceId, stateList);
      this.stateList = new ArrayList<Items>();
      this.stateList.addAll(stateList);
}

  private class ViewHolder
  {

    CheckBox name;
  }

  @Override
 public View getView(int position, View convertView, ViewGroup parent) 
  {

          ViewHolder holder = null;

          Log.v("ConvertView", String.valueOf(position));

          if (convertView == null)
          {

             LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

             convertView = vi.inflate(R.layout.da_item, null);

            holder = new ViewHolder();

            holder.name = (CheckBox) convertView.findViewById(R.id.ingredientbox);

            convertView.setTag(holder);

                      holder.name.setOnClickListener( new View.OnClickListener() 
                      {
                                 public void onClick(View v)  
                                 {
                                   CheckBox cb = (CheckBox) v;
                                   Items _state = (Items) cb.getTag();
                                   _state.setSelected(cb.isChecked());
                                }
                      });

          }
          else
          {
              holder = (ViewHolder) convertView.getTag();
          }

          Items state = stateList.get(position);


          holder.name.setText(state.getName());
          holder.name.setChecked(state.isSelected());

          holder.name.setTag(state);

          return convertView;
  }

}

@Override
public void onActivityCreated(Bundle savedInstanceState){
    super.onActivityCreated(savedInstanceState);



}

     @Override 
     public void onSaveInstanceState(Bundle outState) {
          Log.d("hey","SAVING");                              //NOT SAVING
         super.onSaveInstanceState(outState);
         save();

         outState.putStringArrayList("index", recipesList); 

         }

                }
            }


    }

    }

I found multiple suggestions that said to override the onSaveInstanceState , which I did and I found even more telling me to use setRetainInstance. I don't know why setRetainInstance state would be helpful if I want to save a value of a list. My question-Why Is it not calling the save in the OtherList class or whats a better method to implement if I want to save the values in the List View (in this case I am using checkboxes)

like image 914
user3155092 Avatar asked Jan 02 '14 21:01

user3155092


People also ask

When onSaveInstanceState is called in fragment?

Note that onSaveInstanceState() is called when your activity goes into the background and NOT when the app process is about to be killed.

In which scenario onSaveInstanceState callback method will not be invoked?

The method onSaveInstanceState() isn't called when an Activity finishes naturally like on a back button press. That's your app itself destroying the Activity . The method is only called if the Android OS anticipates that it may have to kill your activity to reclaim resources.

What is life cycle of a fragment?

Fragment life cycle is closely related to the life cycle of its host activity which means when the activity is paused, all the fragments available in the activity will also be stopped. A fragment can implement a behaviour that has no user interface component.

When fragment is DESTROYED?

Fragment is destroyed. As with an Activity , you can save the variable assignments in a Fragment . Because data in a Fragment is usually relevant to the Activity that hosts it, your Activity code can use a callback to retrieve data from the Fragment , and then restore that data when recreating the Fragment .


1 Answers

I had a similar problem where I was trying to get a Fragment to save its state but onSaveInstanceState() wasn't being called on FragmentTransaction.replace(). I was trying to find a solution for this and thought, if the Fragment itself can't save its own state then can't whatever is doing the replacing save it. So I did something like this:

In the Fragment have a method called getState() or whatever you want:

public Bundle getState()
{
    // save whatever you would have in onSaveInstanceState() and return a bundle with the saved data
}

Then in the hosting object, save that bundle to its instance variables before replacing the Fragment and set the argument to that saved bundle when switching back.

FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
// assume Fragment a exists and you're trying to save the state and "state" is an instance variable
state = a.getState();
ft.replace(android.R.id.content, b);

Then when swapping back to Fragment a you would pass the bundle as an argument.

a.setArguments(state);
ft.replace(android.R.id.content, a);

I didn't look into your code too deeply but it sounds similar to the problem I had from your description.

like image 77
dt0 Avatar answered Nov 03 '22 02:11

dt0