【问题标题】:Android - fragmentTransaction.replace() not works on support library 25.1.0Android - fragmentTransaction.replace() 不适用于支持库 25.1.0
【发布时间】:2016-12-15 06:50:36
【问题描述】:

我将 FrameLayout 替换为使用 fragmentTransaction.replace() 的片段。

布局:

<FrameLayout
        android:id="@+id/articlesAppender"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
</FrameLayout>

在Activity的onCreate中替换:

FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
articlesFragment = (ArticlesFragment) fragmentManager.findFragmentByTag(ARTICLES_FRAGMENT_TAG);

if (articlesFragment == null) {
    articlesFragment = new ArticlesFragment();
}

fragmentTransaction.replace(R.id.articlesAppender, articlesFragment, ARTICLES_FRAGMENT_TAG);
fragmentTransaction.commit();

ArticleFragment 的 onCreate:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.articles_fragment, container, false);
    view.setVisibility(View.GONE);
    return view;
}

view.setVisibility(View.GONE); 不适用于支持库 25.1.0。 所以片段仍然会显示在屏幕上。 如果我将articlesAppender 的可见性设置为GONE。 所以它应该是这样的:

<FrameLayout
        android:id="@+id/articlesAppender"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone">
</FrameLayout>

然后该片段将不会在屏幕上可见,但是当我稍后尝试调用view.setVisibility(View.VISIBLE);时,它仍然无法正常工作。 该片段仍然不可见。

这意味着inflater.inflate(R.layout.articles_fragment, container, false);返回的view不是片段的真实视图。 但它在支持库 25.0.1 上完美运行。

所以这是 Android 的错误?

【问题讨论】:

  • 你想用片段替换框架布局吗?
  • 您是如何得出 replace() 方法不起作用的结论的?如果您尝试在该片段布局中的主根元素上而不是在膨胀视图上 setVisibility(View.GONE),它仍然不起作用吗?
  • @RishabhMahatha 是的,我想替换它。 @Gil 因为它适用于支持库 25.0.1。我已经描述了我的问题中的情况。我必须直接设置articleAppender 的可见性。这意味着它没有被替换。膨胀的视图是根元素,这就是我在onCreateView() 中返回此视图的原因。

标签: android fragment android-support-library


【解决方案1】:

已报告问题。更多人似乎有这个问题

https://code.google.com/p/android/issues/detail?id=230191

【讨论】:

  • 而且它不是唯一的。现在,当您交换 2 个视图时,它们会以不同的顺序触发 onStop 和 onStart。所以,我们现在应该坚持使用 25.0.1。
  • “开发团队已解决此问题”正如他们的 pm 所说 code.google.com/p/android/issues/…
  • @Dmitry,该问题的修复方法如下,.setAllowOptimization(false)。我很难学到这一点。
  • @worked 是的,我知道。我在 code.google.com 上发布的问题中提到了这一点。不过,奇怪的是他们没有在发行说明中提到如此重要的变化。
  • @worked 在release notes 中显示“默认情况下禁用此优化。”所以不需要设置为false。
【解决方案2】:

这似乎是一个已报告的错误,如 Gillis Haasnoot 的帖子中所述。

我注意到,如果我将 replace() 拆分为 remove() 和 add(),并使用 commitNow(),它似乎可以按预期工作。

原始代码(从 25.1.0 开始失败):

fragMngr.beginTransation()
    .replace(R.id.detail_container, newFrag, fragTag)
    .commit();

解决方法:

// remove old fragment
Fragment oldFrag = fragMngr.findFragmentByTag(fragTag);
if (oldFrag != null {
    fragMngr.beginTransaction().remove(oldFrag).commitNow();
}

// add new fragment
fragMngr.beginTransaction()
    .add(R.id.detail_container, newFrag, fragTag)
    .commitNow();

【讨论】:

  • 好的;但是认为您有一个非常大的项目,它使用了太多的片段事务。用 commitNow() 结构更改所有 commit() 结构是不合逻辑的。这真的是不必要的工作,不是吗?
  • 当然。这只是在等待实际修复时建议作为一种解决方法。或者您可以恢复到以前版本的支持库。
  • 好建议...有趣的是我正在尝试这种解决方法,但它不起作用...在完成fragMngr.beginTransaction().remove(oldFrag).commitNow(); 之后片段仍然存在,检查fragMngr.findFragmentByTag(fragTag); 它不会返回 null。即使我做一个while循环,它也会创建一个无限循环。知道为什么吗?
  • @HugoAllexisCardona:不,对不起,我不知道为什么。
【解决方案3】:
    //replace fragment
    private void replaceFragment(final Fragment newFragment, final int containerId) {
        final FragmentManager fragmentManager = getFragmentManager();
         final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.replace(containerId, newFragment, newFragment.getClass().getSimpleName());
       fragmentTransaction.commit();
   }

ArticleFragment 的 onCreate:

 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.articles_fragment, container, false);
                return view;
    }

    <FrameLayout
            android:id="@+id/articlesAppender"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    </FrameLayout>

只需在您的 MainActivity onCreate() 中调用此方法 在哪里

newFreagment = "你要替换的片段" containerId = "Framelayout id"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-29
    • 2015-07-03
    • 1970-01-01
    • 2017-05-13
    • 2015-05-22
    相关资源
    最近更新 更多