3

我有一个带有 mode 的ActionBar.NAVIGATION_MODE_TABSActionBar,当我选择不同的选项卡时,我想更改出现在 ActionBar 上的图标。

我用一个 Activity 成功地做到了,但是当我再次将它应用到另一个 Activity 时它表现得很奇怪。

假设我有 2 个选项卡:Tab1 和 Tab2,我希望在选择 Tab2 时出现相机图标,并在选择 Tab1 时消失。此外,Tab1 是活动开始时将选择的第一个选项卡。所以我做了这样的事情:

因为我不希望在 HomeActivity 第一次启动时出现相机图标,所以我设置了android:visible="false",然后当我运行下面的代码时:当 HomeActivity 启动时,相机图标没有出现在 ActionBar -> 正确,但是当我切换到tab2,相机图标也不会出现在 ActionBar 上,但是如果我按下“菜单”按钮 - >“相机”的 MenuItem 将显示为溢出操作栏项目。

如果我设置android:visible="true"-> 除了第一次 HomeActivity 启动时第一次出现相机图标(不正确!!!) -> 当我更改 tab1/tab2 时,相机图标会消失/正确显示。

任何人都可以解释并给我一个解决方案以使其正常工作。谢谢!

这是我的代码:

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
        }       
    }   
}
4

4 回答 4

4

我遇到了同样的问题并找到了一个简单的解决方案:只需在您的 Activity 中实现 onPreparePanel 并返回 true,即使所有项目都不可见。

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 
    }

    [...]

}
于 2013-04-15T06:44:32.267 回答
3

经过一番调查,我认为这是一个错误,但我不知道是ActionBarSherlock的错误还是Android ActionBar的错误。

原因

原因是选项菜单中只有一个MenuItem,假设MenuItem 是mItem。当我设置mItem.setVisible(false)时,ActionBar 上将没有任何项目,那么显然,包含 ActionBar MenuItems 的空间被删除。之后,当我设置时mItem.setVisible(true),空间没有恢复,在这种情况下,我mItem被认为是溢出的MenuItem->它只在使用设备的菜单硬件按钮时显示。

解决方案

  • 使用多个 MenuItem
  • 巧妙地使用setEnable(false)andsetIcon(null)和 and的组合来setTitle("")代替setVisible(false)
于 2012-11-28T17:57:46.683 回答
0

我遇到了同样的问题并以这种方式解决:

首先,我在 onCreateOptionsMenu(Menu menu) 时保存 com.actionbarsherlock.view.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 ) ;
}

然后我检查每个

public boolean onOptionsItemSelected ( MenuItem item )

像这样调用:

@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 );
    }...

希望这可以帮助..

于 2013-11-30T06:14:40.113 回答
0

我遇到了同样的问题,我发现setVisible(true)当至少有另一个MenuItem可见时它可以工作。我希望这对某人有帮助。

于 2014-01-30T10:23:44.857 回答