【问题标题】:Weird fragment lifecycle error奇怪的片段生命周期错误
【发布时间】:2011-05-03 02:35:01
【问题描述】:

编辑

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

原创

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

  • 活动:onCreate()
  • 活动:onResume()
  • 片段:onResume()
  • 旋转屏幕
  • 活动:onCreate()
  • 活动:onResume()
  • 片段:onResume()(即使 Activity.onResume() 设置了项目,项目仍为空)
  • Fragment:onResume()(items 不为 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;
    }
}

【问题讨论】:

    标签: android android-fragments


    【解决方案1】:

    FragmentManager 会自动为我重新创建Fragment。但是,其中的数据需要重新初始化。因此,我的代码正在创建第二个片段。加载屏幕是因为第一个片段不再有它的项目适配器,第二个片段被隐藏了。真令人头疼,我几乎认为FragmentManager 应该销毁Fragments,这样您就可以使用它们持有的数据重新创建它们。

    【讨论】:

    • 很抱歉,我没有太清楚地看到答案......你是如何最终解决这个问题的?我得出了与您相同的结论,但是我找不到轻松解决此问题的方法。这意味着你如何杀死旧片段并使用重新创建的新片段。
    • 如果你想摆脱旧的 Fragment 并使用新的,使用 FragmentTransaction.replace() 函数。然后旧的将被新的替换。只知道必须重新加载数据。
    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

      似乎使用支持库中的FragmentActivity 会自动保存和恢复实例。因此,仅当 savedInstanceStatenull 时才进行片段事务。

      例如,在您的FragmentActivityonCreate() 中,执行以下操作:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-09
        相关资源
        最近更新 更多