[英]Handling orientation changes with Fragments
I'm currently testing my app with a multipane Fragment
-ised view using the HC compatibility package, and having a lot of difficultly handling orientation changes.我目前正在使用 HC 兼容性 package 使用多窗格Fragment
视图测试我的应用程序,并且有很多难以处理的方向更改。
My Host
activity has 2 panes in landscape ( menuFrame
and contentFrame
), and only menuFrame
in portrait, to which appropriate fragments are loaded.我的Host
活动有 2 个横向窗格( menuFrame
和contentFrame
),只有纵向的menuFrame
,其中加载了适当的片段。 If I have something in both panes, but then change the orientation to portrait I get a NPE as it tries to load views in the fragment which would be in the (non-existent) contentFrame
.如果我在两个窗格中都有一些东西,但是然后将方向更改为纵向,我会得到一个 NPE,因为它试图在(不存在的) contentFrame
中的片段中加载视图。 Using the setRetainState()
method in the content fragment didn't work.在内容片段中使用setRetainState()
方法不起作用。 How can I sort this out to prevent the system loading a fragment that won't be shown?我该如何解决这个问题以防止系统加载不会显示的片段?
Many thanks!非常感谢!
It seems that the onCreateViewMethod
was causing issues;似乎onCreateViewMethod
引起了问题; it must return null if the container is null:如果容器是 null,它必须返回 null:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (container == null) // must put this in
return null;
return inflater.inflate(R.layout.<layout>, container, false);
}
This does the trick:这可以解决问题:
Create a new Instance of Fragment when the activity start for the first time else reuse the old fragment.当活动第一次启动时创建一个新的片段实例,否则重用旧片段。
How can you do this?你怎么能这样做?
FragmentManager is the key FragmentManager是关键
Here is the code snippet:这是代码片段:
if(savedInstanceState==null) {
userFragment = UserNameFragment.newInstance();
fragmentManager.beginTransaction().add(R.id.profile, userFragment, "TAG").commit();
}
else {
userFragment = fragmentManager.findFragmentByTag("TAG");
}
Save data on the fragment side在 Fragment 端保存数据
If your fragment has EditText, TextViews or any other class variables which you want to save while orientation change.如果您的片段有 EditText、TextViews 或任何其他您想要在方向更改时保存的 class 变量。 Save it
onSaveInstanceState()
and Retrieve them inonCreateView()
method保存它onSaveInstanceState()
并在onCreateView()
方法中检索它们
Here is the code snippet:这是代码片段:
// Saving State
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("USER_NAME", username.getText().toString());
outState.putString("PASSWORD", password.getText().toString());
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.user_name_fragment, parent, false);
username = (EditText) view.findViewById(R.id.username);
password = (EditText) view.findViewById(R.id.password);
// Retriving value
if (savedInstanceState != null) {
username.setText(savedInstanceState.getString("USER_NAME"));
password.setText(savedInstanceState.getString("PASSWORD"));
}
return view;
}
Probably not the ideal answer but if you have contentFrame
for portrait and in your activity only load up the menuFrame
when the savedInstanceState is null then your content frame fragments will be shown on an orientation change.可能不是理想的答案,但如果您有纵向的contentFrame
并且在您的活动中仅在 savedInstanceState 为menuFrame
时加载 menuFrame,那么您的内容框架片段将在方向更改时显示。
Not ideal though as then if you hit the back button (as many times as necessary) then you'll never see the menu fragment as it wasn't loaded into contentFrame
.虽然不理想,但如果您点击后退按钮(根据需要多次),那么您将永远不会看到菜单片段,因为它没有加载到contentFrame
中。
It is a shame that the FragmentLayout API demos doesn't preserve the right fragment state across an orientation change.遗憾的是,FragmentLayout API 演示没有在方向更改时保留正确的片段 state。 Regardless, having thought about this problem a fair bit, and tried out various things, I'm not sure that there is a straightforward answer.无论如何,在考虑过这个问题并尝试了各种事情之后,我不确定是否有一个简单的答案。 The best answer that I have come up with so far (not tested) is to have the same layout in portrait and landscape but hide the menuFrame
when there is something in the detailsFrame
.到目前为止,我想出的最佳答案(未经测试)是纵向和横向具有相同的布局,但在detailsFrame
中有内容时隐藏menuFrame
。 Similarly show it, and hide frameLayout
when the latter is empty.同样显示它,当后者为空时隐藏frameLayout
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.