奇怪的碎片生命周期错误



编辑

所以我的Fragment似乎保留在试图重新初始化它的FragmentManager中。仍然不确定为什么它没有用Activity销毁。至于加载消息,当ListView没有设置适配器时会显示此消息。然而,我在onCreateonResume中设置了适配器项,所以我不确定为什么会显示这个加载屏幕。对这种行为的任何解释仍然开放

原始

我在玩碎片,注意到当我改变屏幕的方向时出现了一个奇怪的错误。但是,这个错误不应该发生,因为当屏幕方向改变时,所有数据都会在onCreate中重新创建。此外,片段onResume()在旋转之后被调用两次。以下是我创建错误的步骤,以及调试器如何处理函数。

  • 活动:onCreate((
  • 活动:onResume((
  • 片段:onResume((
  • 旋转屏幕
  • 活动:onCreate((
  • 活动:onResume((
  • 片段:onResume(((项为null,即使Activity.onResume((设置了它们(
  • 片段:onResume(((项不为null,为什么要调用两次?(

命中最后一个片段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,这样你就可以用它们保存的数据重新创建它们。

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

IIRC,片段创建的东西会调用默认的构造函数来创建,但只知道通过setArguments填充适当的数据。在android开发博客上的例子中。。。id是从listactivity传递到details片段的。调用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
}

最新更新