Android - fragmentTransaction.replace() not works

2020-06-17 05:43发布

问题:

I replace a FrameLayout with a fragment using fragmentTransaction.replace().

Layout:

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

Replacing in Activity's 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's 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;
}

But the view.setVisibility(View.GONE); is not working on support library 25.1.0. So the fragment will still be displayed on the screen. If I set the visibility of the articlesAppender to GONE. So it should look like this:

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

Then the the fragment will not be visible on the screen, but when I try to call view.setVisibility(View.VISIBLE); later, it still not works. The fragment still not be visible.

That means the view which is returned by inflater.inflate(R.layout.articles_fragment, container, false); is not the real view of the fragment. But it works perfectly on support library 25.0.1.

So it's an Android's bug?

回答1:

issue is reported. more people seems to have this issue

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



回答2:

It seems to be a reported bug, as noted in Gillis Haasnoot's post.

I noticed that if I split replace() into remove() and add(), and use commitNow() it seems to work as expected.

Original code (fails starting with 25.1.0):

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

Work-around:

// 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();


回答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's 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>

Just call this method in your MainActivity onCreate() Where

newFreagment = "Fragment you want to replace with" containerId = "Framelayout id"