Ollie C
Ollie C

Reputation: 28509

Dynamic changing of the text color of Toolbar MenuItem text

In the app I am working on colors for various UI elements come from an HTTP response, ie coloring is done at runtime, and cannot be done using Android theming.

Other questions exist on this topic, but most are using themes, or if dynamic code, the code is not working. For example using spans:

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

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    menuItemGoalSave = menu.findItem(R.id.action_goal_edit_save);
    SpannableString s = new SpannableString(menuItemGoalSave.getTitle() + "XX");
    ForegroundColorSpan span = new ForegroundColorSpan(Color.RED);
    s.setSpan(span, 0, s.length(), 0);
    menuItemGoalSave.setTitle(s);
    return true;
}

Or similar approaches applying HTML strings.

The code above in theory applies a span with coloring, but although the title has "XX" appended (ie the code is running, and affecting the menu item) the colour does not change.

Is there any way to dynamically affect the color of this Toolbar action item text?

Upvotes: 1

Views: 741

Answers (2)

Stas Lelyuk
Stas Lelyuk

Reputation: 548

Updated

Also it works as expected in case if you're using 'Toolbar' directly. See example

public class MainActivity extends AppCompatActivity implements Toolbar.OnMenuItemClickListener {

    private Toolbar mToolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        mToolbar.inflateMenu(R.menu.menu_main);
        mToolbar.setOnMenuItemClickListener(this);
    }

    private void applyMenuItemTextColor() {
        MenuItem item = mToolbar.getMenu().findItem(R.id.action_settings);
        SpannableString s = new SpannableString(item.getTitle());
        ForegroundColorSpan span = new ForegroundColorSpan(System.currentTimeMillis() % 2 == 0 ? Color.RED :Color.GREEN);
        s.setSpan(span, 0, s.length(), 0);
        item.setTitle(s);
    }

    @Override
    public boolean onMenuItemClick(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            applyMenuItemTextColor();//supportInvalidateOptionsMenu();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

Original answer

Your spans example works as expected. See results:

enter image description here

enter image description here

Here's code used for this sample:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
    }

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

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        MenuItem item = menu.findItem(R.id.action_settings);
        SpannableString s = new SpannableString(item.getTitle());
        ForegroundColorSpan span = new ForegroundColorSpan(System.currentTimeMillis() % 2 == 0 ? Color.RED :Color.GREEN);
        s.setSpan(span, 0, s.length(), 0);
        item.setTitle(s);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            supportInvalidateOptionsMenu();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

I hope this will be helpful. Please let me know if there are any questions.

Upvotes: 2

Zubin Kadva
Zubin Kadva

Reputation: 601

Try this:

TextView liveitem = (TextView )mOptionsMenu.findItem(R.id.action_live);
liveitem.setTextColor(Color.RED);

Upvotes: 0

Related Questions