I have one activity with exactly one fragment in it. The fragment adds one item to the activity's action bar.
Now when the app runs some time, the user leaves it to do other stuff and returns to the app, there is an additional menu item (i.e. the fragment's item added again). From two item we get three, four, five and so on.
How is it possible that the fragment's menu item is added multiple times?
activity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_conversations_list);
mToolbar = Ui.setupActionbar(this, false);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.contentframe, new ConversationsFragment());
fragmentTransaction.commit();
}
fragment
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// has it's own actionbar items
setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.appbar_menu_conversations_list, menu);
}
appbar_menu_conversations_list.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_refresh"
android:title="@string/action_sync"
app:showAsAction="always"
android:icon="@drawable/ic_sync_white_24dp"/>
</menu>
You are actually adding the Fragment to the activity multiple times, so it gets multiple menu items. Since the Activity's FragmentManager stores its state on rotation, you need to only add the Fragment in onCreate the first time. You can confirm this by rotating the device and seeing new items added (rotation isn't the only way it'll happen, but an easy one to reproduce).
To do this, simple wrap the Fragment transaction in a test:
if (savedInstanceState == null) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.contentframe, new ConversationsFragment());
fragmentTransaction.commit();
}
After the first time the activity is created, on things like orientation changes, savedInstanceState will be a bundle, but the first time it will be null, so that's a good way to check that things only happen once.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With