启用/禁用ActionBar菜单项

27

我有一个ActionBar菜单项,分别是取消和保存。

menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:id="@+id/saveButton" 
          android:showAsAction="always"          
          android:title="@string/save" 
          android:visible="true">

    </item>
    <item android:id="@+id/cancelButton" 
          android:showAsAction="always"         
          android:title="@string/cancel" 
          android:visible="true">        
    </item>

</menu>
我希望您开始活动时禁用保存菜单项。
我的活动代码 -
@Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.add_project);

        EditText projectName = (EditText) findViewById(R.id.editTextProjectName);   
        projectName.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                configureSaveButton(s);             
            }           
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,int after) {}
            @Override
            public void afterTextChanged(Editable s) {}
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.addprojectmenu, menu);      
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        MenuItem item = (MenuItem) findViewById(R.id.saveButton);
        item.setEnabled(false);     
        return super.onPrepareOptionsMenu(menu);
    }

    private void configureSaveButton(CharSequence s){
        String text = null;
        if(s != null){
            text = s.toString();
        }       
        if(text != null && text.trim().length() != 0){

        }else{

        }
    }

所以我在这里尝试做的是,最初活动开始时保存菜单项应该被禁用,在editext包含某些文本时它应该被启用。

我不确定configureSaveButton方法中if else中的代码应该是什么。 还有,我如何最初禁用保存菜单项。

我在onPrepareOptionsMenu中得到空指针异常。

我正在使用Android 4.1。


尝试这个:最好的方法禁用菜单项图标https://dev59.com/C2035IYBdhLWcg3wZ_Mt#33910273 - Prashant Gosai
4个回答

30
@Override
public boolean onPrepareOptionsMenu(Menu menu) {

    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.addprojectmenu, menu);      

    menu.getItem(0).setEnabled(false); // here pass the index of save menu item
    return super.onPrepareOptionsMenu(menu);

}

只需要在准备时间充气它,然后在充气菜单后禁用,不需要在onCreateOptionsMenu时间内充气或者你可以在从onCreateOptionMenu充气之后只使用最后两行代码。

@Override
public boolean onPrepareOptionsMenu(Menu menu) {

    menu.getItem(0).setEnabled(false); // here pass the index of save menu item
    return super.onPrepareOptionsMenu(menu);

}

12
当您希望更新选项菜单时,您还需要调用invalidateOptionsMenu() - dmon
谢谢您的回答,我该如何重新启用它?在configureSaveButton方法中应该写什么代码? - Coder
请问使用Pratik的代码后,我们应该在哪里调用invalidateOptionsMenu()函数? - Coder
1
您可以获取菜单项并将其保存在MenuItem对象中,然后根据需要设置其值,最后调用invalidateOptionsMenu()方法来更新ActionBar菜单。 - Pratik
我认为这并不推荐。特别是在棒棒糖系统中,禁用的项目看起来像启用的项目。因此用户无法区分它们两个。 - Eugen Martynov
显示剩余5条评论

16

我发现这篇帖子,因为我想要达到相同的结果。其他答案都没有完全帮助我使它工作。经过一些研究和试错,我让我的工作起来了。所以我决定分享我的结果。

我为这个任务创建的变量:

MenuItem save_btn;
boolean b = false;`

然后设置操作栏菜单:

    @Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.update_menu_item, menu);
    save_btn = (MenuItem) menu.findItem(R.id.action_save);
    return true;
}

@Override
public boolean onPrepareOptionsMenu(Menu menu){
    save_btn.setEnabled(b);
    super.onPrepareOptionsMenu(menu);       
    return true;
}

由于变量boolean b被初始化为false,因此在创建活动时禁用save_btn按钮。

以下是使用@OpenSourceRulzz示例切换save_btn的方法:

private void updateSaveButton (CharSequence s){
    String text = null;
    if(s != null){
        text = s.toString();
    }
    if(text != null && text.trim().length() != 0){
        b = true;
    }
    else{
        b = false;
    }
}

这种方法是通过在onCreate()中再次使用@OpenSourceRulzz的示例,为EditText框架调用TextWatcher()函数实现的。

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.add_project);

    EditText projectName = (EditText) findViewById(R.id.editTextProjectName);   
    projectName.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            updateSaveButton(s);
            invalidateOptionsMenu();
        }           
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,int after){}
        @Override
        public void afterTextChanged(Editable s) {}
    });
}

拼图的最后一块是添加invalidateOptionsMenu()方法。

我想出来的部分是使用boolean b变量来切换save_btn的状态,使我的代码能够工作。


2
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    if (your condition) {
        menu.findItem(R.id.saveButton).setEnabled(false);
    } else {
        menu.findItem(R;id.saveButton).setEnabled(true);
    }     
    return super.onPrepareOptionsMenu(menu);
}

使用这种方法,每次检查条件时,您的菜单项将被禁用,并且如果不是,则会启用。


2

在遇到这个愚蠢问题后我苦苦思索了1小时,唯一可行的解决方法是:

把菜单存储在一个本地变量中:

Menu menu;

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    this.menu = menu;
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

只需调用以下方法来更改启用状态:

menu.findItem(R.id.action_save).setEnabled(true);

而且你可以在xml文件中最初禁用它……


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接