opticon
opticon

Reputation: 3594

Change Chromecast casting icon color

I'm using Google's method to add a Cast button to my app, but it's defaulted to the white icon, which is invisible against my white menu bar. How do I go about changing the color of the Cast icon to black?

Upvotes: 8

Views: 8624

Answers (8)

oziem
oziem

Reputation: 470

I've just extended MediaRouteActionProvider like this:

    public class ThemeableMediaRouteActionProvider extends MediaRouteActionProvider {
    public ThemeableMediaRouteActionProvider(Context context) {
        super(context);
    }

    @Override
    public MediaRouteButton onCreateMediaRouteButton() {
        MediaRouteButton button = super.onCreateMediaRouteButton();
        colorWorkaroundForCastIcon(button);
        return button;
    }

    @Nullable
    @Override
    public MediaRouteButton getMediaRouteButton() {
        MediaRouteButton button = super.getMediaRouteButton();
        colorWorkaroundForCastIcon(button);
        return button;
    }

    private void colorWorkaroundForCastIcon(MediaRouteButton button) {
        if (button == null) return;
        Context castContext = new ContextThemeWrapper(getContext(), androidx.mediarouter.R.style.Theme_MediaRouter);

        TypedArray a = castContext.obtainStyledAttributes(null, androidx.mediarouter.R.styleable.MediaRouteButton, androidx.mediarouter.R.attr.mediaRouteButtonStyle, 0);
        Drawable drawable = a.getDrawable(androidx.mediarouter.R.styleable.MediaRouteButton_externalRouteEnabledDrawable);
        a.recycle();
        DrawableCompat.setTint(drawable, getContext().getResources().getColor(R.color.primary));
        drawable.setState(button.getDrawableState());
        button.setRemoteIndicatorDrawable(drawable);
    }
}

R.color.primary is what color i wanted.

then just replace actionProviderClass in menu from MediaRouteActionProvider to your like that:

<item
    android:id="@+id/media_route_menu_item"
    android:title="@string/media_route_menu_title"
    bwq:actionProviderClass="tv.test.playback.chromecast.ThemeableMediaRouteActionProvider"
    bwq:showAsAction="always">
</item>

Upvotes: 9

RamPrasadBismil
RamPrasadBismil

Reputation: 589

If none of the above solution work, try what has been explained here. You might need to use the colorFilter property instead of tint.

  public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    inflater.inflate(R.menu.some_menu, menu);
    setColorForCast(menu);
  }

  private void setColorForCast(@NonNull Menu menu) {
    MediaRouteButton castButton = (MediaRouteButton) menu.findItem(R.id.cast_button).getActionView();
    if (castButton != null) {
      Drawable drawable = getResources().getDrawable(R.drawable.chromecast);
      int color = ContextCompat.getColor(getContext(), R.color.colorPrimary);
      drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
      drawable.setState(castButton.getDrawableState());
      castButton.setRemoteIndicatorDrawable(drawable);
    }
  }



Upvotes: 0

Geekygecko
Geekygecko

Reputation: 3972

If you have a one color for the cast icon for a view use a theme for the fragment or activity.

<item name="mediaRouteButtonTint">@color/red</item>

If you want to programmatically set the color use the following code.

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/menu_item"
        android:title="@string/media_route_menu_title"
        app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider" />
</menu>
import androidx.core.content.ContextCompat
import androidx.appcompat.view.ContextThemeWrapper
import androidx.core.graphics.drawable.DrawableCompat

...

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater?) {
    val tintColor = ContextCompat.getColor(context, R.color.my_color)
    val item = menu.findItem(R.id.menu_item)
    val button = item.actionView
    val castContext = ContextThemeWrapper(context, androidx.mediarouter.R.style.Theme_MediaRouter)
    val attrs = castContext.obtainStyledAttributes(null, androidx.mediarouter.R.styleable.MediaRouteButton, androidx.mediarouter.R.attr.mediaRouteButtonStyle, 0)
    val drawable = attrs.getDrawable(androidx.mediarouter.R.styleable.MediaRouteButton_externalRouteEnabledDrawable)
    attrs.recycle()
    DrawableCompat.setTint(drawable, tintColor)
    drawable.state = button.getDrawableState()
    button.setRemoteIndicatorDrawable(drawable)

Upvotes: 7

Jake Lee
Jake Lee

Reputation: 7979

The official answer is here:

https://developers.google.com/cast/docs/android_sender/customize_ui#customize_cast_button

Customize Cast Button

To add a custom mediaRouteTheme to your app's Theme:

<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
  <!-- ... -->
  <item name="mediaRouteTheme">@style/CustomMediaRouterTheme</item>
</style>

Declare your custom Media Router theme and declare a custom mediaRouteButtonStyle:

<style name="CustomMediaRouterTheme" parent="Theme.MediaRouter">
  <item name="mediaRouteButtonStyle">@style/CustomMediaRouteButtonStyle</item>
</style>

<style name="CustomMediaRouteButtonStyle" parent="Widget.MediaRouter.Light.MediaRouteButton">
  <item name="mediaRouteButtonTint">#EEFF41</item>
</style>

mediaRouteButtonTint should be used if the support library version is newer than 26.0.0. For older support library versions, please use buttonTint instead.

Upvotes: 6

Petr Tykal
Petr Tykal

Reputation: 21

Absolutely simple answer's here:

https://developers.google.com/cast/docs/android_sender_advanced#customize_cast_button


So just copy mediaRouteTheme from that link to your app's theme and next two styles to the styles.xml.

Upvotes: 0

hitch45
hitch45

Reputation: 492

I extended MediaRouteButton. See code below. Then I can just call applyTint() and it applies the color to all states of the RemoteIndicatorDrawable

public class ColorableMediaRouteButton extends MediaRouteButton {

    protected Drawable mRemoteIndicatorDrawable;

    public ColorableMediaRouteButton(Context context) {
        super(context);
    }

    public ColorableMediaRouteButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ColorableMediaRouteButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void setRemoteIndicatorDrawable(Drawable d) {
        mRemoteIndicatorDrawable = d;
        super.setRemoteIndicatorDrawable(d);
    }

    public void applyTint(int color) {
        Drawable wrapDrawable = DrawableCompat.wrap(mRemoteIndicatorDrawable);
        DrawableCompat.setTint(wrapDrawable, color);
    }
}

Upvotes: 3

jaolstad
jaolstad

Reputation: 605

I experienced this issue myself, and solved it by changing the android:theme and app:popuptheme values to @style/ThemeOverlay.AppCompat.Dark.ActionBar.

See example code below:

<android.support.v7.widget.Toolbar
        android:id="@+id/my_toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="#4dffffff"
        android:elevation="4dp"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>

Upvotes: 1

Ali Naddaf
Ali Naddaf

Reputation: 19044

If it is just due to the style (dark vs light), you should be fine if the style is defined correctly (i.e. extending the right theme in terms of dark vs light). For general styling, check out this post and if that doesn't solve your issue, come back and let us know.

Upvotes: 2

Related Questions