我的片段被创建了两次,即使活动仅将片段添加到内容中一次 . 旋转屏幕时会发生这种情况 . 此外,每次调用片段的onCreateView时,它都会丢失所有可变状态 .
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) { // Checking for recreation
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new AppPanelFragment())
.commit();
}
}
}
onCreate在活动中检查null savedInstanceState,并且只有null将添加片段,所以我不明白为什么片段应该被创建两次?在if条件中设置断点告诉我它只被调用一次,因此活动不应该多次添加片段 . 但是,每次方向更改时,仍然会调用片段的onCreateView .
public class AppPanelFragment extends Fragment {
private TextView appNameText;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// This method called several times
View rootView = inflater.inflate(R.layout.fragment_app_panel, container, false);
// 2nd call on this method, appNameText is null, why?
appNameText = (TextView) rootView.findViewById(R.id.app_name);
appNameText.text = "My new App";
return view;
}
我设法使用setRetainInstance(true)保持变量状态,但这是真正的解决方案吗?我希望片段不会仅仅在方向改变时创建 .
4 回答
在android中,当手机的方向改变时,活动将被销毁并重新创建 . 现在,我相信要解决您的问题,您可以使用片段管理器检查片段是否已经存在于后端堆栈中,如果它不存在则创建它 .
附:我没有测试过这个,但是一旦你在findFragmentById方法中提供了正确的片段id,它就应该可以工作了 .
Fragment
生命周期与Activity
非常相似 . 默认情况下,是的,它们将在配置更改期间重新创建,就像Activity
一样 . 这是预期的行为 . 即使使用了setRetainInstance(true)
(我会说如果它包含一个UI我会非常谨慎地使用),你的View
将被销毁并重新创建,但在这种情况下你的Fragment
实例不会被销毁 - 只有View
.如上所述,在方向更改时,活动将被销毁并重新创建 . 此外,系统会重新创建片段(任何) .
为确保应用程序恢复到以前的状态,在销毁活动之前调用onSaveInstanceState() .
因此,您可以在活动的onSaveInstanceState()方法中存储一些信息,然后在方向更改时将应用程序恢复到相同的状态 .
注意:您不需要在方向更改时创建片段,因为会重新创建片段 .
http://www.mynewsfeed.x10.mx/articles/index.php?id=15中的示例:
我知道回答有点迟,但使用The Code Pimp回答你可以做下一件事:
如果片段存在于backstack中,我们会弹出并将其删除以将其添加回来(如果在不删除它的情况下将其添加回来,则会抛出异常,说它已经存在) .
fragment变量是一个类成员变量 .
此方法将在Activity的onCreate方法中调用:
下一个代码将在片段本身中调用 .
这是您可以在片段中实现的代码的一个小示例,以了解它的工作原理 . dummyTV是片段中心的简单文本视图,它根据方向接收文本(为此我们需要一个计数器) .