Search code examples
androidactionbarsherlockhandlermenuitem

Change MenuItem title and icon when Handler gets message


I want to change the title and icon when the connection state changes... the updateMenuTitle() is from here and works because I've test it but is not working when I call the updateMenuTitle() from handler the app crashes at start

 private void updateMenuTitle(int x) {
    MenuItem btstatus = menu.findItem(R.id.btstatus);
    if (x == 1) {
        btstatus.setTitle("Connected");
        btstatus.setIcon(R.drawable.ic_btstatus_on);
    } else if (x == 2){
        btstatus.setTitle("Connecting");
        btstatus.setIcon(R.drawable.ic_btstatus_idle);
    }else if (x == 0){
        btstatus.setTitle("Disconnected");
        btstatus.setIcon(R.drawable.ic_btstatus_off);
    }
}

private final Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case MESSAGE_STATE_CHANGE:
            switch (msg.arg1) {
            case BluetoothRfcommClient.STATE_CONNECTED:
                mTxtStatus.setText(R.string.title_connected_to);
                mTxtStatus.append(" " + mConnectedDeviceName);
                updateMenuTitle(1);//not working if I call it from here... app force close
                break;
            case BluetoothRfcommClient.STATE_CONNECTING:
                mTxtStatus.setText(R.string.title_connecting);
                updateMenuTitle(2);//not working if I call it from here... app force close
                break;
            case BluetoothRfcommClient.STATE_NONE:
                mTxtStatus.setText(R.string.title_not_connected);
                updateMenuTitle(0);//not working if I call it from here... app force close
                break;
            }
            break;
            .......

Solution:

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        if (mChangedStat && mChangedStat2) {
            menu.findItem(R.id.btstatus).setTitle(R.string.title_connected);
            menu.findItem(R.id.btstatus).setIcon(R.drawable.ic_btstatus_on);
        } else if (!mChangedStat && mChangedStat2) {
            menu.findItem(R.id.btstatus).setTitle(R.string.title_connecting);
            menu.findItem(R.id.btstatus).setIcon(R.drawable.ic_btstatus_idle);
        } else if (!mChangedStat && !mChangedStat2) {
            menu.findItem(R.id.btstatus).setTitle(R.string.title_not_connected);
            menu.findItem(R.id.btstatus).setIcon(R.drawable.ic_btstatus_off);
        }
}

    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case MESSAGE_STATE_CHANGE:
                                switch (msg.arg1) {
            case BluetoothServiceClient.STATE_CONNECTED:
                mChangedStat = true;
                mChangedStat2 = true;
                supportInvalidateOptionsMenu();
                break;
            case BluetoothServiceClient.STATE_CONNECTING:
                mChangedStat = false;
                mChangedStat2 = true;
                supportInvalidateOptionsMenu();
                break;
            case BluetoothServiceClient.STATE_NONE:
                mChangedStat = false;
                mChangedStat2 = false;
                supportInvalidateOptionsMenu();
                break;
            }
                break;
                .......

Solution

  • Im doing a little different:

    private boolean flag = false;
    
    void someMethod() {
    
       flag = true;
       invalidateOptionsMenu();
    
    }
    
    public boolean onCreateOptionsMenu (Menu menu) {
    
        if (flag) {
          // inflate menu 1
        } else {
          // inflate menu 2
        }
    

    }

    On this way you dont need to handle messages or something. You only need to manage menu items on onCreateOptionsMenu.