安卓碎片替换没有任何反应

3
我希望有人能够澄清我在这里做错了什么。我在横屏模式下的平板电脑上使用了常见的主细节架构。唯一的注意事项是,主区域中的某些元素会在详细信息部分打开FragA,而其他元素则会在详细信息部分打开FragB。一切似乎都很好,除了实际切换片段的过程。无论哪个片段首先显示,只会显示一个。我一直在使用replace方法来交换它们,我找到的所有关于此主题的SO评论都指出,如果我已经将详细信息片段添加到XML中,则这种方法不起作用。不幸的是,对我来说,这并不适用,因为我动态地添加所有片段。我的代码如下:
FragmentInfo frag = (Helper.isImageViewable(fileSelected)) ?  getFragInfoByClass(ImageViewerFragment.class) : getFragInfoByClass(DownloadProgressFragment.class) ;
         FragmentTransaction ft = getFragmentManager().beginTransaction();
         if(frag.mFragment == null){
             frag.mFragment = Fragment.instantiate(NewMainActivity.this, frag.mClass.getName());
             ft.add(frag.target.getId(), frag.mFragment);
             ft.commit();
             ft = getFragmentManager().beginTransaction();
         } 
         ft.replace(frag.target.getId(), frag.mFragment);
         ft.commit();

这是添加这些片段的唯一代码,并且似乎发生的是先添加的片段可以正常工作,但替换方法根本不起作用。无论哪个片段都会保留在那里。
有谁知道我做错了什么吗?
编辑:
与布局文件相关的部分如下:
    <LinearLayout
    android:id="@+id/fragments_holder"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <FrameLayout
        android:id="@+id/list_fragment"
        android:layout_width="0dp"
        android:layout_weight="0.39"
        android:layout_height="match_parent" />

    <FrameLayout
        android:id="@+id/details_fragment"
        android:layout_height="match_parent"
        android:layout_weight="0.61"
        android:layout_width="0dp" />

    <!-- ADD METADATA VIEW HERE -->

</LinearLayout>

两个 FragmentInfo 对象的目标都正确指向 id/details_fragment 的 FrameLayout,这也说明如果其中任意一个首先被添加,它们都能正常工作。

编辑 2 注意:使用此代码块也会得到完全相同的结果:

FragmentInfo frag = (Helper.isImageViewable(fileSelected)) ?  getFragInfoByClass(ImageViewerFragment.class) : getFragInfoByClass(DownloadProgressFragment.class) ;
         FragmentTransaction ft = getFragmentManager().beginTransaction();
         if(frag.mFragment == null){
             frag.mFragment = Fragment.instantiate(NewMainActivity.this, frag.mClass.getName());
             ft.add(frag.target.getId(), frag.mFragment);
             //ft.commit();
             //ft = getFragmentManager().beginTransaction();
         } else{
             ft.replace(frag.target.getId(), frag.mFragment);
         }
         //ft.replace(frag.target.getId(), frag.mFragment);
         ft.commit();
         detailsContainer.setFragmentInfo(frag);

编辑后的内容为:“虽然我认为这并不重要,因为无论添加哪个片段,第一个添加的片段都会正确显示。” - akhalsa
1个回答

1

Replace(替换)实际上等同于一系列的删除和添加操作。即使容器为空,使用replace也是安全的(此时等同于简单的添加)。我更喜欢使用明确的删除和添加操作,因为这样更容易理解。

我认为你的代码示例在开始时存在一些问题,但一旦初始化完成,似乎有一些正确的路径通过它。在第一个代码示例中,当片段尚未创建时,您正在使用相同的片段实例调用add和replace。在第二个代码示例中,在第二个要添加的片段尚未创建时,您没有删除旧的片段。

我认为如果您注释掉(删除)双重添加,您的第一个代码示例将执行正确的替换操作:

FragmentInfo frag = (Helper.isImageViewable(fileSelected)) ?  getFragInfoByClass(ImageViewerFragment.class) : getFragInfoByClass(DownloadProgressFragment.class) ;
         FragmentTransaction ft = getFragmentManager().beginTransaction();
         if(frag.mFragment == null){
             frag.mFragment = Fragment.instantiate(NewMainActivity.this, frag.mClass.getName());
             // ft.add(frag.target.getId(), frag.mFragment);
             // ft.commit();
             // ft = getFragmentManager().beginTransaction();
         } 
         ft.replace(frag.target.getId(), frag.mFragment);
         ft.commit();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接