nuuneoi / StatedFragment

Deprecated
473 stars 82 forks source link

onSaveInstanceState is not called but the view state is retained #1

Open thmiles opened 9 years ago

thmiles commented 9 years ago

i have read your blog http://inthecheesefactory.com/blog/best-approach-to-keep-android-fragment-state/en great work, and i wrote some example base on Case 2: Fragment in Back Stack, But the result is not the same as what you said,although onSaveInstanceState is not called, the view state is retained ,here is piece of code:

public class DynamicFragmentA extends Fragment {

private static final String TAG = DynamicFragmentA.class.getSimpleName();
private EditText tvState;
private Button btnGoto;
private String txt = "";
private ListView listView;
private SAdapter adapter;

@Override
public View onCreateView(LayoutInflater inflater,
        @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    Log.i(TAG, "onCreateView");
    View v = inflater.inflate(R.layout.dynamic_fragment_main_a, container,false);
    tvState = (EditText) v.findViewById(R.id.tvState);
    btnGoto = (Button) v.findViewById(R.id.btnGoto);
    tvState.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            txt = tvState.getText().toString();
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {
        }

        @Override
        public void afterTextChanged(Editable s) {
        }
    });
    Log.d(TAG, "savedInstanceState is "+(savedInstanceState==null?"null":savedInstanceState.toString()));
    Log.d(TAG, "member txt: "+txt);
    btnGoto.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            FragmentManager fgmManager = getActivity().getSupportFragmentManager();
            FragmentTransaction fgmTransaction = fgmManager.beginTransaction();
            fgmTransaction.replace(R.id.fgmContainer, new DynamicFragmentB(),"dyn_fgm_b");
            fgmTransaction.addToBackStack(null);
            fgmTransaction.commit();
        }
    });

    listView = (ListView) v.findViewById(R.id.listView);
    adapter = new SAdapter(getActivity());
    listView.setAdapter(adapter);

    return v;
}
nuuneoi commented 9 years ago

If View is designed to retain its view's state internally, it would be retained when fragment is back from backstack.

Please try the following cases:

Case 1: TextView without android:freezeText=true <== TextView's text would not be retained

Case 2: TextView with android:freezeText=true (and don't forget to assign android:id as well) <== TextView's text would be retained

Case 3: EditText with android:id assigned <== EditText's text would be retained.

Anyway the point is when you choose to use those 3rd party View(s) available over the internet, I found that those views are rarely implemented an internal view state saving/restoring. That's why we need a workaround and it becomes StatedFragment in this repository.