Reputation: 1443
I have an ActionBar with mode ActionBar.NAVIGATION_MODE_TABS
, I want to change icons which appear on ActionBar when I choose different tabs.
I did it successfully with an Activity, but it acted weird when I applied it again on another Activity.
Let's say I have 2 tabs: Tab1 and Tab2, and I want a Camera icon to appear when Tab2 is being chosen and disappear when Tab1 is being chosen. Moreover, Tab1 is the first tab will be chosen when the activity start. So I did something like this:
Because I don't want the camera icon to appear at the first time HomeActivity start, so I set android:visible="false"
, then when I run below code: when HomeActivity starts, camera icon doesn't appear on ActionBar -> correct, but when I switch to tab2, camera icon doesn't appear on ActionBar too, but if I press "Menu" button -> a MenuItem which is "Camera" appears as an overflow actionbar item.
And if I set android:visible="true"
-> except the camera icon appears at the first time first time HomeActivity start (incorrect!!!) -> then camera icon disappears/appears correctly when I change tab1/tab2.
Can anyone explain and give me a solution to make it works correctly. Thanks!
This is my code:
actionbar_home.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/actionbar_home_camera"
android:title="@string/actionbar_rc_camera"
android:icon="@drawable/ic_action_camera"
android:showAsAction="always"
android:visible="false"/>
</menu>
HomeActivity.java
public class HomeActivity extends SherlockFragmentActivity {
private ActionBar actionBar;
private Menu menu;
private Tab1Fragment tab1Fragment;
private Tab2Fragment tab2Fragment;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
this.configActionBar();
this.createTabs();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.actionbar_home, menu);
this.menu = menu;
// pass objects to tabs
tab1Fragment.setOptionMenu(this.menu);
tab2Fragment.setOptionMenu(this.menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
private void configActionBar()
{
actionBar = this.getSupportActionBar();
// below line makes application icon in top-left corner become a button
actionBar.setHomeButtonEnabled(true);
// below line add an arrow "<" before the top-left icon
//ab.setDisplayHomeAsUpEnabled(true);
//actionBar.setDisplayShowTitleEnabled(true);
}
private void createTabs()
{
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab tab1 = actionBar.newTab().setText(
Const.TAB_TITLE_HOME_TAB1);
ActionBar.Tab tab2 = actionBar.newTab().setText(
Const.TAB_TITLE_HOME_TAB2);
// create the two fragments we want to use for display content
tab1Fragment = new Tab1Fragment();
tab2Fragment = new Tab2Fragment();
// add listener
tab1.setTabListener(
new HomeTabListener(tab1Fragment));
tab2.setTabListener(
new HomeTabListener(tab2Fragment));
actionBar.addTab(tab1);
actionBar.addTab(tab2);
}
}
BaseTabFragment.java
public class BaseTabFragment extends SherlockFragment{
protected View root;
protected Menu optionMenu;
protected SherlockFragmentActivity container;
public Menu getOptionMenu() {
return optionMenu;
}
public void setOptionMenu(Menu optionMenu) {
this.optionMenu = optionMenu;
}
public SherlockFragmentActivity getContainer() {
return container;
}
public void setContainer(SherlockFragmentActivity container) {
this.container = container;
}
}
Tab1Fragment.java
public class Tab1Fragment extends BaseTabFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
root = inflater.inflate(R.layout.tab1_layout,
container, false);
this.changeActionBarLayout();
return root;
}
private void changeActionBarLayout()
{
try {
this.optionMenu.findItem(R.id.actionbar_home_camera)
.setVisible(false);
} catch (NullPointerException e)
{
// e will be thrown at the first time MainActivity is called
}
}
}
Tab2Fragment.java
public class Tab2Fragment extends BaseTabFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
root = inflater.inflate(R.layout.tab2_layout,
container, false);
this.changeActionBarLayout();
return root;
}
private void changeActionBarLayout()
{
try {
this.optionMenu.findItem(R.id.actionbar_home_camera)
.setVisible(true);
// Camera Icon still doesn't appear on ActionBar even when I set it as SHOW_AS_ACTION_ALWAYS
this.optionMenu.findItem(R.id.actionbar_home_camera)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
} catch (NullPointerException e)
{
// e will be thrown at the first time MainActivity is called
}
}
}
Upvotes: 3
Views: 3034
Reputation: 4733
I had the same problem and I found out that setVisible(true)
works when there is at least another MenuItem
visible. I hope this can be helpful to someone.
Upvotes: 0
Reputation: 1295
I faced the same problem and solved in this way:
Firstly I save the com.actionbarsherlock.view.Menu when onCreateOptionsMenu(Menu menu)
@Override
public boolean onCreateOptionsMenu ( Menu menu )
{
ShowOrEditTaskActivity.this.getSupportMenuInflater().inflate(R.menu.edit_or_show_task_menu, menu);
setOptionsMenu ( menu );
optionsMenu.findItem ( R.id.save_action ).setVisible ( false );
return super.onCreateOptionsMenu ( menu ) ;
}
Then I check in every
public boolean onOptionsItemSelected ( MenuItem item )
call like this:
@Override
public boolean onOptionsItemSelected ( MenuItem item )
{
if ( item.getItemId ( ) == R.id.edit_action )
{
isEditMode ( true ) ;
optionsMenu.findItem ( R.id.edit_action ).setVisible ( false );
optionsMenu.findItem ( R.id.save_action ).setVisible ( true );
}...
Hope this helps..
Upvotes: 0
Reputation: 200
I had the same problem and found an easy solution for it: Just implement onPreparePanel in your Activity and return true even if all items are invisible.
public class HomeActivity extends SherlockFragmentActivity {
[...]
@Override
public boolean onPreparePanel(int featureId, View view, Menu menu) {
super.onPreparePanel(featureId, view, menu); // this returns false if all items are hidden
return true; // return true to prevent the menu's deletion
}
[...]
}
Upvotes: 4
Reputation: 1443
After some investigation, I think this is a bug, but I don't know it's ActionBarSherlock's bug or Android ActionBar's bug.
Reason
The reason is because of there's ONLY ONE MenuItem in option menu, let's say the MenuItem is mItem. When I set mItem.setVisible(false)
, there will be no item left on ActionBar, then apparently, the space which contains ActionBar MenuItems is removed. After that, when I set mItem.setVisible(true)
, the space is not restored, in that case, my mItem
is considered as an overflow MenuItem -> it's only revealed when use Menu hardware button of devices.
Solution
setEnable(false)
and setIcon(null)
and setTitle("")
instead of setVisible(false)
Upvotes: 3