Reputation: 3329
I try to implement an activity which can load different fragments into one container view element. I follow the Building a Flexible UI Training. Problem: When replacing a fragment, I can still see the replaced fragment in the background.
I see that my question has already been asked numerous times. However all the answers I found seem to be just a workaround (setting the background-color of fragments) or do not apply.
Here is what I have setup so far:
The activity's XML layout contains one FrameLayout as a container for the fragments:
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
The id fragment_container
is used nowhere else in the project.
The complete XML layout of the first fragment:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="First Fragment" />
The complete XML layout of the second fragment:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="#ff0000"
android:text="Fragment Second" />
The class file of the first fragment looks like this (class for second fragment analogous):
public class FirstFragment extends Fragment {
public FirstFragment() {}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_first, container, false);
}
}
In the activity's onCreate method I load the first fragment:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// load first fragment
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, new FirstFragment())
.commit();
}
}
When selecting a menu item I try to replace the first fragment with the second fragment with this code in the activity's onOptionsItemSelected
method:
getFragmentManager().beginTransaction()
.replace(R.id.fragment_container, new SecondFragment())
.addToBackStack(null) // <-- does not make any difference if left out
.commit();
The result is that the text "Fragment Second" is printed in red above the text "First Fragment".
What is the "right way" (i.e. not just setting a background-color) to fix this problem?
Upvotes: 1
Views: 3846
Reputation: 30985
I noticed this in onCreate
:
getSupportFragmentManager()
and this in onOptionsItemSelected
:
getFragmentManager()
There are actually both versions of the FragmentManager
in AppCompatActivity
and they know nothing about each other. So when you tell android.app.FragmentManager
to replace a fragment that was added by android.support.v4.app.FragmentManager
, it doesn't know anything about a FirstFragment
so the operation acts more like an add than a replace.
I've made this mistake more than once. You'll need to comb through your code and make sure you are consistent about using the support class vs. the regular class.
Upvotes: 3