findFragmentById返回不存在的片段

时间:2015-04-02 21:20:17

标签: android android-layout android-fragments android-fragmentactivity

我有以下2个布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <fragment android:id="@+id/list_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        class="MyListFragment"/>

</LinearLayout>

(w900dp)

<fragment android:id="@+id/list_fragment"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight=".3"
    class="MyListFragment"/>

<fragment android:id="@+id/content_fragment"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight=".7"
    class="MyContentFragment"/>

然后在我的活动中我有:

public class ReportActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.report);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        // Get the content fragment
        MyContentFragment contentFragment = (MyContentFragment) getSupportFragmentManager().findFragmentById(R.id.content_fragment);
        if (contentFragment != null) {
           // sometimes I get a handle to this fragment when I should not
           contentFragment.updateContent(//some content);
        }
    }

我的问题是这个。当我以横向模式启动应用程序时,宽度足够宽以显示两个片段。当我旋转到肖像时它不再宽,没有加载内容片段的布局文件。但是,当我调用片段管理器来获取该片段时,它会找到它。然后当我调用失败的更新内容时,因为该片段中的UI组件不再存在。

为什么getFragmentById返回一个确实存在的片段,但在设备轮换后不再存在?

1 个答案:

答案 0 :(得分:0)

我怀疑问题是你的getFragmentById()调用正在返回原始片段 - 在横向启动应用程序时创建的片段。可能是在旋转期间重新创建活动时,该片段已分离(但未销毁),然后将实例添加到活动中。你的getFragmentById()有效,但是它返回的(原始)Fragment已经分离,所以它没有膨胀的布局 - 所以更新内容调用失败。

如果没有更多的活动代码,很难解决问题。您应确保在创建活动期间,创建和附加片段时,首先检查并查看它是否已存在于片段管理器中。

....
Fragment frag = fragmentManager.findFragById(id);
if (frag == null) {
    frag = MyFrag.newInstance();
}
fragmentManager.replace(...,frag,...)...

我实际上会使用findFragmentByTag(),因为我发现更容易跟踪哪个片段。只需确保在更换碎片时设置唯一标记。