简体   繁体   English

使用 Fragments 处理方向变化

[英]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 个横向窗格( menuFramecontentFrame ),只有纵向的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);
}

Create new Instance only for First Time.仅为第一次创建新实例。

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 in onCreateView() 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;
}

You can see the full working code HERE您可以在此处查看完整的工作代码

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM