在onStart中恢复Fragment的ViewState?

8
当屏幕方向改变时,片段viewState仅在onStart中恢复。 在onAttachonCreateViewonViewCreatedonActivityCreated甚至在onCreate之后都是如此。 为什么?这太晚了。
我需要根据某些TextView值将db查询结果填充到ListView中。目前我尝试在onViewCreated中完成此操作。但是在此步骤中未恢复视图状态。
我可以强制提前恢复吗? 或如何解决此问题? 请给出任何想法。
PS:我使用actionbarsherlock和依赖于android support-v4 r7库
PS2:如果我在onStart中加载数据,则在停止onStop后恢复片段时会进行其他查询(我可以通过添加一些布尔isLoaded来解决此问题-但这不是最佳解决方案)。
3个回答

13
在Android API>=17(Android4.2 Jelly Beans)中,有一个方法: public void onViewStateRestored (Bundle savedInstanceState)文档所述,在onStart()之前和onActivityCreated()之后调用。
在Android API < 17中没有这种方法。但有两个解决方案:
1. 不要在初始化Fragment时依赖视图状态,并将所有所需的初始化状态保存为Fragment状态(即重写Fragment#onSaveInstanceState())。稍后可以在onCreate()onCreateView()onViewCreated()中恢复片段状态。
2. 如问题所述,在onStart()中执行初始化。

4

[编辑1 - - - - - - -]

// 检查片段回退栈是否已经被填充

// 如果没有,创建并填充布局。

// 这样你的片段不会重新创建

  YourFragment yourFragment = (YourFragment )fm.findFragmentById(R.id.fragment_container);

  if (yourFragment == null) {
       FragmentTransaction ft = fm.beginTransaction(); 
       ft.replace(R.id.fragment_container, new YourFragment ());       
       ft.commit();
  }

[编辑1 - - - - - - -]

在此输入图片描述

这是一张关于IT技术的图片,但具体内容无法确定。
/**
 * Listing 4-4: Fragment skeleton code
 * Listing 4-5: Fragment lifecycle event handlers
 */
package com.paad.fragments;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class MySkeletonFragment extends Fragment {

  // Called when the Fragment is attached to its parent Activity.
  @Override
  public void onAttach(Activity activity) {
    super.onAttach(activity);
    // Get a reference to the parent Activity.
  }

  // Called to do the initial creation of the Fragment.
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Initialize the Fragment.
  }

  // Called once the Fragment has been created in order for it to
  // create its user interface.
  @Override
  public View onCreateView(LayoutInflater inflater, 
                           ViewGroup container,
                           Bundle savedInstanceState) {
    // Create, or inflate the Fragment's UI, and return it. 
    // If this Fragment has no UI then return null.
    return inflater.inflate(R.layout.my_fragment, container, false);
  }



  // Called once the parent Activity and the Fragment's UI have 
  // been created.
  @Override
  public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    // Complete the Fragment initialization Ğ particularly anything
    // that requires the parent Activity to be initialized or the 
    // Fragment's view to be fully inflated.
  }

  // Called at the start of the visible lifetime.
  @Override
  public void onStart(){
    super.onStart();
    // Apply any required UI change now that the Fragment is visible.
  }

  // Called at the start of the active lifetime.
  @Override
  public void onResume(){
    super.onResume();
    // Resume any paused UI updates, threads, or processes required
    // by the Fragment but suspended when it became inactive.
  }

  // Called at the end of the active lifetime.
  @Override
  public void onPause(){
    // Suspend UI updates, threads, or CPU intensive processes
    // that don't need to be updated when the Activity isn't
    // the active foreground activity.
    // Persist all edits or state changes
    // as after this call the process is likely to be killed.
    super.onPause();
  }

  // Called to save UI state changes at the
  // end of the active lifecycle.
  @Override
  public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save UI state changes to the savedInstanceState.
    // This bundle will be passed to onCreate, onCreateView, and
    // onCreateView if the parent Activity is killed and restarted.
    super.onSaveInstanceState(savedInstanceState);
  }

  // Called at the end of the visible lifetime.
  @Override
  public void onStop(){
    // Suspend remaining UI updates, threads, or processing
    // that aren't required when the Fragment isn't visible.
    super.onStop();
  }

  // Called when the Fragment's View has been detached.
  @Override
  public void onDestroyView() {
    // Clean up resources related to the View.
    super.onDestroyView();
  }

  // Called at the end of the full lifetime.
  @Override
  public void onDestroy(){
    // Clean up any resources including ending threads,
    // closing database connections etc.
    super.onDestroy();
  }

  // Called when the Fragment has been detached from its parent Activity.
  @Override
  public void onDetach() {
    super.onDetach();
  }
}
:《专业Android开发4》- Reto Meier

您需要在每次屏幕方向更改时更改值吗? - Talha
不,当屏幕方向改变时,我需要从数据库重新加载数据。但是查询需要“搜索”字符串参数。我从TextView#getValue()获取此“搜索”参数,但在方向更改后,片段将被重新创建并且TextView值将丢失。它稍后将恢复,仅在“onStart”中。 - acc15
请查看编辑后的答案,如果您检查了片段返回堆栈,它将解决您的问题。 - Talha
不正确。除非您调用 setRetainInstance(true) 或在 AndroidManifest.xml 中设置 android:configChanges="orientation",否则片段(以及包含的整个活动)将在方向更改时始终重新创建。请在此处阅读:http://developer.android.com/guide/topics/resources/runtime-changes.html - acc15
为了防止屏幕方向改变时数据丢失,您只需要在清单文件中更改一行即可:/ - An-droid
显示剩余6条评论

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接