Android - 保存/恢复片段状态

Sta*_*ete 46 android fragment onresume android-fragments back-stack

我有一个活动,其中我经历了几个片段.在每个片段中,我都有几个视图(EditText, ListView, Map等).

如何保存当时显示的片段实例?我需要它在活动时工作onPause() --> onResume().当我从另一个片段(从backstack弹出)返回时,我需要它才能工作.

从主要的Activity我调用第一个片段,然后从片段我调用下一个片段.

我的活动代码:

public class Activity_Main extends FragmentActivity{

public static Fragment_1 fragment_1;
public static Fragment_2 fragment_2;
public static Fragment_3 fragment_3;
public static FragmentManager fragmentManager;

@Override
 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

     fragment_1 = new Fragment_1();

     fragment_2 = new Fragment_2();

     fragment_3 = new Fragment_3();

     fragmentManager = getSupportFragmentManager();
     FragmentTransaction transaction_1 = fragmentManager.beginTransaction();
     transaction_1.replace(R.id.content_frame, fragment_1);
     transaction_1.commit();
}}
Run Code Online (Sandbox Code Playgroud)

然后这是我的一个片段的代码:

public class Fragment_1 extends Fragment {

      private EditText title;
      private Button go_next;


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

            View rootView = inflater.inflate(R.layout.fragment_1,
            container, false);

            title = (EditText) rootView.findViewById(R.id.title);

            go_next = (Button) rootView.findViewById(R.id.go_next);

            image.setOnClickListener(new View.OnClickListener() {

         @Override
         public void onClick(View v) {

                 FragmentTransaction transaction_2 = Activity_Main.fragmentManager
                .beginTransaction();

                 transaction_2.replace(R.id.content_frame,
                  Activity_Main.fragment_2);
                 transaction_2.addToBackStack(null);
                 transaction_2.commit();  

            });
        }}
Run Code Online (Sandbox Code Playgroud)

我搜索了很多信息,但没有任何明确的信息.请问有人给出一个明确的解决方案和一个例子吗?

Kir*_*man 82

当片段移动到后台堆栈时,它不会被销毁.所有实例变量都保留在那里.所以这是保存数据的地方.在onActivityCreated您检查以下条件:

  1. 是捆绑!= null?如果是,则保存数据(可能是方向更改).
  2. 实例变量中是否保存了数据?如果是的话,从他们那里恢复你的状态(或者什么也不做,因为一切都是应该的).
  3. 否则,您的片段将首次显示,重新创建所有内容.

编辑:这是一个例子

public class ExampleFragment extends Fragment {
    private List<String> myData;

    @Override
    public void onSaveInstanceState(final Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putSerializable("list", (Serializable) myData);
    }

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

        if (savedInstanceState != null) {
            //probably orientation change
            myData = (List<String>) savedInstanceState.getSerializable("list");
        } else {
            if (myData != null) {
                //returning from backstack, data is fine, do nothing
            } else {
                //newly created, compute data
                myData = computeData();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Stanete是这个帖子的解决方案吗?如果是的话考虑标记它. (4认同)

neb*_*yan 16

Android片段有一些优点和一些缺点.片段的最大缺点是,当您想要使用片段时,您可以创建片段.使用它时,onCreateView每次调用片段.如果要保留片段中组件的状态,则必须保存片段状态,并且必须在下一个显示中加载其状态.这使片段视图有点慢和奇怪.

我找到了一个解决方案,我已经使用了这个解决方案:"一切都很棒.每个人都可以尝试".

第一次onCreateView运行时,将视图创建为全局变量.当第二次调用此片段onCreateView再次调用时,您可以返回此全局视图.将保留片段组件状态.

View view;

@Override
public View onCreateView(LayoutInflater inflater,
        @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    setActionBar(null);
    if (view != null) {
        if ((ViewGroup)view.getParent() != null)
            ((ViewGroup)view.getParent()).removeView(view);
        return view; 
    }
    view = inflater.inflate(R.layout.mylayout, container, false);
}
Run Code Online (Sandbox Code Playgroud)


Sar*_*Sar 7

试试这个 :

@Override
protected void onPause() {
    super.onPause();
    if (getSupportFragmentManager().findFragmentByTag("MyFragment") != null)
        getSupportFragmentManager().findFragmentByTag("MyFragment").setRetainInstance(true);
}

@Override
protected void onResume() {
    super.onResume();
    if (getSupportFragmentManager().findFragmentByTag("MyFragment") != null)
        getSupportFragmentManager().findFragmentByTag("MyFragment").getRetainInstance();
}
Run Code Online (Sandbox Code Playgroud)

希望这会有所帮助.

你也可以把这个写到menifest文件中的activity标签:

  android:configChanges="orientation|screenSize"
Run Code Online (Sandbox Code Playgroud)

祝好运 !!!

  • `android:configChanges ="orientation | screenSize"`会导致很多其他问题,因为它会覆盖正常的Android行为.这很可能会增加意想不到的错误.我建议不要使用它. (7认同)
  • 给出空指针异常. (4认同)

Raa*_*nan 5

为了保存 Fragment 状态,您需要实现onSaveInstanceState():“也像一个活动一样,您可以使用 Bundle 保留一个Fragment 的状态,以防 Activity 的进程被终止,并且您需要在重新创建活动时恢复Fragment 状态你可以在片段的过程中保存状态onSaveInstanceState()回调过程中,可以还原onCreate()onCreateView()onActivityCreated()欲了解更多信息有关保存状态,看到活动的文件。”

http://developer.android.com/guide/components/fragments.html#Lifecycle