I realize I\'m probably doing something fundamentally wrong with styles and themes but I\'m still a bit of an Android newbie so please excuse my ignorance. I\'m trying to c
If you don't want to change the color of the icon, framework would choose the right one (dark or light) based on the theme of your actionbar, so for an actionbar with light background, it will choose a darker icon and vice versa; here is a sample app with two different themes, Theme.AppCompat.Light and Theme.AppCompat, respectively (everything else is identical):
As you can see, the appropriate one is selected automatically. If you want to use a different color based on your branding requirements, the easiest would be to add the following images to your project (with usual resolutions under mdpi, hdpi, ..):
(if you are using a light actionbar theme, replace "dark" with "light"). Take a look at the assets at Google Cast > Sample Apps (section Cast Icons) to get a feel for what these images are and build your own ones based on those.
I ended up decompiling android-support-v7-mediarouter.jar to see what was going on. With the code available I was able to extend MediaRouteButton and set the private Drawable through reflection hacking. There has to be a better way right?
public class CustomMediaRouteButton extends MediaRouteButton {
private static final String TAG = "CustomMediaRouteButton";
public CustomMediaRouteButton(Context context){
this(context, null);
}
public CustomMediaRouteButton(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.mediaRouteButtonStyle);
}
public CustomMediaRouteButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
Drawable d = getResources().getDrawable(R.drawable.mr_ic_media_route_holo_light);
setRemoteIndicatorDrawable(d);
}
private void setRemoteIndicatorDrawable(Drawable d) {
try {
Field field = MediaRouteButton.class.getDeclaredField("mRemoteIndicator");
field.setAccessible(true);
Drawable remoteIndicator = (Drawable)field.get(this);
if (remoteIndicator != null) {
remoteIndicator.setCallback(null);
unscheduleDrawable(remoteIndicator);
}
field.set(this, d);
if (d != null) {
d.setCallback(this);
d.setState(getDrawableState());
d.setVisible(getVisibility() == 0, false);
}
} catch (Exception e) {
Log.e(TAG, "problem changing drawable:" + e.getMessage());
}
refreshDrawableState();
}
}
You can change it easily now with your custom drawable. Just call this method on your cast button.
mediaRouteButton = (MediaRouteButton) findViewById(R.id.media_route_button);
mediaRouteButton.setRemoteIndicatorDrawable(yourDrawable);
If you want to change the icons used (not just the style), you need to name them the exact same way they are named here. For instance, for the light theme, you need to have a set of icons for every resolution with names: ic_cast_on_light.png
, ic_cast_on_0_light.png
, ic_cast_on_1_light.png
, ic_cast_on_2_light.png
, ic_cast_disabled_light.png
, ic_cast_off_light.png
.
You should be able to change the style by applying the style to your activity, e.g. in AndroidManifest.xml. If you want to change the drawable, I succeeded by adding mr_ic_media_route_holo_light drawable to my project. Just add it to drawables folder and customize it as you need it. Example: https://github.com/android/platform_frameworks_support/blob/master/v7/mediarouter/res/drawable/mr_ic_media_route_holo_light.xml
I found a way to change your color of MediaRouteButton by code, and is easy to be done, no need to touch existing code.
The MediaRouteButton will style itself following the theme of context which you passed. You can create a ContextThemeWrapper to wrap the context and then pass it to MediaRouteActionProvider.
Following is an example:
MenuItem item = menu.add(Menu.NONE, R.id.menu_cast, Menu.NONE, "Cast");
MenuItemCompat.setActionProvider(item, new MediaRouteActionProvider(new ContextThemeWrapper(this, R.style.AppTheme)));
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
Here the R.style.AppTheme is a theme which extends from Theme.AppCompat, it is a dark theme so the cast button will always show in light version. You can also pass in light theme to make cast button behave in dark version. Also you can change it dynamically, just invalidate the option menu, it should recreate the action provider using the new theme.
I am using support library 23.1.1 and have not found any problem in this way.