怪异片段生命周期误差

问题描述:

编辑怪异片段生命周期误差

如此看来,我的Fragment保留在它试图重新初始化它的FragmentManager。仍然不确定为什么它不会被Activity破坏。至于加载消息,这在ListView没有设置适配器时显示。但是,我在onCreateonResume中设置了适配器项目,因此我不确定为什么会显示此加载屏幕。仍然是开放的这种行为

原始

我与碎片玩耍,并注意到,在弹出当我改变屏幕的方向一个奇怪的错误任何解释。这个错误不应该发生,因为所有的数据都是在屏幕方向改变时在onCreate中重新创建的。此外,片段onResume()在旋转后被调用两次。这是我创建错误的步骤以及调试器如何实现这些功能。

  • 活动:的onCreate()
  • 活动:的onResume()
  • 片段:的onResume()
  • 旋转屏幕
  • 活动:的onCreate()
  • 活动:的onResume()
  • 片段:onResume()(即使Activity.onResume()设置它们,项目为null)
  • 片段:onResume()(items不为空,这是为什么被称为两次?)

这最后一个片段onResume之后被击中,平板显示“载入中...”消息和图标。为什么数据不再显示在列表中?我的怀疑是onCreate正在创建第二个片段。第一个片段由于方向破坏视图而丢失数据,第二个片段获取数据,加载屏幕是第一个没有数据项的片段,第二个片段被隐藏。我可能是错的。为什么当屏幕像Activity那样旋转时,碎片不会全部被破坏?除非它解决这个具体问题,否则请不要批评代码。我实际上并没有制作应用,我正在尝试片段功能。谢谢!

主要活动

private ArrayList<Object> items = new ArrayList<Object>(); 
private MyListFragment mylistFragment; 

public MainActivity() { 
    items.add("Hello"); 
    items.add("World"); 
    items.add("Goodbye"); 
} 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    FragmentManager fm = getFragmentManager(); 
    FragmentTransaction ft = fm.beginTransaction(); 

    mylistFragment = new MyListFragment(); 
    mylistFragment.setItems(items); 

    ft.add(R.id.container, mylistFragment); 
    ft.commit(); 
} 

@Override 
public void onResume() { 
    super.onResume(); 

    mylistFragment.setItems(items); 
    mylistFragment.getListView().setOnItemClickListener(new OnItemClickListener() { 
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
      Toast.makeText(MainActivity.this, ((TextView)view).getText(), Toast.LENGTH_LONG).show(); 
     } 

    }); 
} 

名单片段

private List<Object> items = null; 
private Boolean isSet = false; 

@Override 
public void onResume() { 
    super.onResume(); 
    if(!isSet && items != null) { 
     setListAdapter(new ArrayAdapter<Object>(getActivity(), R.layout.item, items)); 
     isSet = true; 
    } 
} 

public void setItems(List<Object> items) { 
    this.items = items; 
    if(this.isResumed()) { 
     setListAdapter(new ArrayAdapter<Object>(getActivity(), R.layout.item, items)); 
     isSet = true; 
    } else { 
     isSet = false; 
    } 
} 

FragmentManager将自动重新创建Fragment我。但是,它们中的数据需要重新初始化。因此我的代码创建了第二个片段。加载屏幕是因为第一个片段不再有项目的适配器,第二个片段被隐藏。真让人头痛,我几乎认为FragmentManager应该销毁Fragments,所以你可以用它们保存的数据重新创建它们。

+1

对不起,但是我没有看到答案得太清楚......你怎么收场解决这个问题呢?我得出了和你一样的结论,但是我找不到解决这个问题的方法。这意味着你如何杀死旧的碎片并使用重新创建的新碎片。 – Maurycy 2012-03-16 06:18:51

+0

如果你想摆脱旧的Fragment并使用新的,使用FragmentTransaction.replace()函数。然后旧的将被替换为新的。只要知道数据将不得不重新加载。 – Spidy 2012-03-18 05:18:29

我相信这就是为什么在通过Diane和其他谷歌示例的各种演示中......他们通常会通过静态方法...和setArguments来帮助初始化初始化。

IIRC,片段创建的东西将调用默认的构造函数来创建,但只知道通过setArguments填充适当的数据。在android开发博客中的示例中,id从列表活动传递到细节片段。在setParams被调用之后,fragmentManager应该能够重新创建它。

文档似乎对这个主题很少,我希望做的事情正确,所以如果你们有反馈,我会很感激。

似乎从支持库使用FragmentActivity自动保存和恢复实例。因此,只有在savedInstanceStatenull的情况下才进行碎片交易。

例如,在你的FragmentActivityonCreate(),请执行下列操作:

if(savedInstanceState == null){ 
     FragmentManager fragmentManager = getSupportFragmentManager(); 
     fragmentManager.beginTransaction() 
     .replace(R.id.fragment_container, mFragment).commit(); //mFragment is your own defined fragment 
}