I know there is LOT of code but please read the first paragraph and go further if you need more info ! Thanks!
I want to display contextual menu item in my 3 tabs activity (no view pager), just static tabs. The main activity is the ActionTab.listener. I used ActionBarActivity with action bar compat. The code for the main activity is below. I used the Google docs to attach and detach fragments (that are created if they are null the first time). Here is my LogCat, you can see that onCreateOptionMenu is called for each existing fragment even when only one is attached and displayed Why?
LogCat:
V/MainActivity(22555): on create MainActivity (application starts)
V/onTabSelected(22555): starting
E/MainActivity(22555): frag 1 is null
V/onTabSelected(22555): add fragment 1 (creates 1st fragment)
D/Fragment1(22555): on Attach
D/Fragment1(22555): on create
D/Fragment1(22555): - onCreateOPTIONMenu (all is fine)
D/Fragment1(22555): on create View
D/Fragment1(22555): on Activity Created
D/Fragment1(22555): on Start
D/Fragment1(22555): on Resume
D/dalvikvm(22555): GC_CONCURRENT freed 159K, 4% free 9115K/9415K, paused 1ms+2ms
D/CLIPBOARD(22555): Hide Clipboard dialog at Starting input: finished by someone else... !
V/on Tab Un-selected(22555): starting (I selecte TAB2 : callback on unselect Tab1)
V/on Tab 1 Unselected(22555): detach frag1 (FragTransac.detach(frag1) has been passed)
V/onTabSelected(22555): starting
E/MainActivity(22555): frag 2 is null (ok that creates frag2)
V/onTabSelected(22555): add fragment 2
D/Fragment2(22555): on Attach
D/Fragment1(22555): - onCreateOPTIONMenu (Why is it called, you are detached, frag1!)
D/Fragment2(22555): - onCreateOPTIONMenu (frag2 ok)
D/Fragment2(22555): on create
D/Fragment2(22555): on create View
D/Fragment2(22555): on Activity Created
D/Fragment2(22555): on Start
D/Fragment2(22555): on Resume
V/on Tab Un-selected(22555): starting
V/on Tab 2 Unselected(22555): detach frag2
V/onTabSelected(22555): starting
E/MainActivity(22555): frag 3 is null
V/onTabSelected(22555): add fragment 3
D/Fragment3(22555): on Attach
D/Fragment1(22555): - onCreateOPTIONMenu (again problem)
D/Fragment2(22555): - onCreateOPTIONMenu (problem repeated for frag2)
D/Fragment3(22555): - onCreateOPTIONMenu (behavior I expect for frag3)
D/Fragment3(22555): on create
D/Fragment3(22555): on Activity Created
D/Fragment3(22555): on Start
D/Fragment3(22555): on Resume
This is my main activity code: The main activity is the ActionTab.listener. I used ActionBarActivity with action bar compat. The code for the main activity is below. I used the Google docs to attach and detach fragments (that are created if they are null the first time).
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v("MainActivity", "on create MainActivity");
// Set the Action Bar to use tabs for navigation
ab = getSupportActionBar();
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
tab1 = ab.newTab().setText("Tab 1").setTabListener(this);
ab.addTab(tab1);
tab2 = ab.newTab().setText("Tab 2").setTabListener(this);
ab.addTab(tab2);
tab3 = ab.newTab().setText("Tab 3").setTabListener(this);
ab.addTab(tab3);
}
@Override
public void onResume(){
super.onResume();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate menu from menu resource (res/menu/main)
getMenuInflater().inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
public boolean isInBooking() {
return isInBooking;
}
// Implemented from ActionBar.TabListener
@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
// This is called when a tab is selected.
Log.v("onTabSelected", "starting");
switch(tab.getPosition()){
case 0:
if (frag1==null) {
Log.e(TAG, "frag 1 is null");
frag1 = new Fragment1();
ft.add(android.R.id.content, frag1);
Log.v("onTabSelected", "add fragment 1");
}else {
ft.attach(frag1);
Log.v("onTabSelected", "Attach fragment 1");
}
break;
case 1:
if (frag2==null) {
Log.e(TAG, "frag 2 is null");
frag2 = new Fragment2();
ft.add(android.R.id.content, frag2);
Log.v("onTabSelected", "add fragment 2");
} else {
ft.attach(frag2);
Log.v("onTabSelected", "Attach fragment 2");
}
break;
case 2:
if (frag3==null) {
Log.e(TAG, "frag 3 is null");
frag3 = new Fragment3();
ft.add(android.R.id.content, frag3);
Log.v("onTabSelected", "add fragment 3");
} else {
ft.attach(frag3);
Log.v("onTabSelected", "Attach fragment 3");
}
break;
default:
break;
}
}
// Implemented from ActionBar.TabListener
@Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
// This is called when a previously selected tab is unselected.
Log.v("on Tab Un-selected", "starting");
switch(tab.getPosition()){
case 0:
ft.detach(frag1);
Log.v("on Tab 1 Unselected", "detach frag1");
break;
case 1:
ft.detach(frag2);
Log.v("on Tab 2 Unselected", "detach frag2");
break;
case 2:
ft.detach( frag3);
Log.v("on Tab 3 Unselected", "detach frag3");
break;
default:
break;
}
}
The fragments are built as extension of Fragment. Here is the fragment onCreateOptionsMenu(). I put setHasOption to true. Maybe I should wraped this in a control as I saw on the CommonsWare example here but I don't understand how and why should I do that?
@Override
public void onCreateOptionsMenu(android.view.Menu menu, android.view.MenuInflater inflater) {
if(!isDetached()) {
Log.d(TAG, " - onCreateOPTIONMenu");
inflater.inflate(R.menu.fragment1, menu);
} else Log.v(TAG, "not attached - onCreateOPTIONMenu");
}
I also tried isAdded() or isHidden with no good results (always hidden, always added). But I do have calls detach and attach, What is going on here?
This is linked to this explanation: https://groups.google.com/forum/#!msg/android-platform/QlkLMsncDwg/u3iZ-q7FCVkJ
In the end I left that simple implementation to go with a view pager that is more powerful and more refined, I feel. It natively manages correctly the menu and provides nice animation transition.