Preventing Fragment restoreViewState()

眉间皱痕 提交于 2020-01-30 06:00:31

问题


I have an object Foo which can be configured using a fragment (FooFragment). The Foo class contains a static reference to FooFragment and the method public Fragment getConfigurationFragment(); this method assigns the current object to the FooFragment and returns it.

public class Foo{
    private static FooFragment fooFragment = new FooFragment();

    public Fragment getConfigurationFragment(){
        fooFragment.setObject(this);
        return fooFragment;
    }

    //various getters and setters
}

FooFragment is roughly as follows:

public class FooFragment extends Fragment{
    private Foo f;

    private EditText field1, field2, etc;

    public void setObject(Foo f){
        this.f = f;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        //inflate view
        setupFieldListeners();
        //return view object
    }

    @Override
    private void onStart(){
        super.onStart();
        setupFields();
    }

    private void setupFields(){
        field1.setText(f.getField1());
        field2.setText(f.getField2());
        //etc
    }

    private void setupListeners(){
         field1.addTextChangedListener(new TextWatcher(){
             @Override
             public void afterTextChanged(Editable e){
                 f.setField1(e.getText().toString());
         });
             //Other empty necessary methods

         field2.addTextChangedListener(new TextWatcher(){
             //...
         });
    }
}

When I use the Fragment for the first time on object foo1, everything works great. The proper information is displayed and everything works.

When I use the Fragment for the second time on another object foo2, opening the Fragment causes all of the properties from foo1 (field1, field2, etc) to be written to the foo2. I believe that this is because when the Fragment is added again, the restoreViewState() method runs, which changes the values of the EditText fields to the values for foo1, causing the afterTextChanged() method to fire, and writing the values of foo1 into foo2.

I have tried the following to fix the problem:

-Creating a new FooFragment object whenever getConfigurationFragment() is called. This works, but I believe it's not optimal, as I understand that it's good to avoid needlessly creating objects on a mobile platform.

-Overriding onSaveInstanceState() in the Fragment and sending a null Bundle. This doesn't work as it doesn't look to be called when the Fragment is closed. It doesn't work.

-Placing the setupFields() call in OnStart(), OnResume(), OnCreateView(). None of these work as when the restoreViewState() runs, it clobbers foo2 object.

-Setting the Bundle to null in onCreate() and onCreateView(). Doesn't work.

What can I do to get the foo2 information to load into the reused Fragment?

I do not have the best understanding of the FragmentTransaction mechanism. Is it possible to somehow tell the FragmentManager to restore the View state?

Is the idea of reusing a configuration Fragment as I'm trying to do fundamentally flawed and to be avoided? If so why?

Is there some other magic that will cause this to work?

Thanks in advance for your time.


回答1:


I had a similar struggle with fragment view state restoration. One way to prevent it was to clear package-private mSavedViewState field before restoreViewState() is called:

package androidx.fragment.app;

import android.os.Bundle;
import android.view.View;

public class StatelessFragment extends Fragment {

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        mSavedViewState = null;
    }
}


来源:https://stackoverflow.com/questions/28015159/preventing-fragment-restoreviewstate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!