Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I change the style of the MediaRouteButton in the ActionBar?

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 change the style of my MediaRouteButton from the default dark to light since I have a light ActionBar. My MediaRouteButton is implemented in the ActionBar as follows:

<item
    android:id="@+id/menu_item_cast"
    android:actionProviderClass="android.support.v7.app.MediaRouteActionProvider"
    android:actionViewClass="android.support.v7.app.MediaRouteButton"
    android:showAsAction="always"
    android:actionButtonStyle="@android:style/Theme.MediaRouter.Light"/>

However, this gives me:

android/res/menu/main.xml:24: error: Error: No resource found that matches the given name (at 'actionButtonStyle' with value '@android:style/Theme.MediaRouter.Light').

like image 567
ActiveApathy Avatar asked Oct 09 '13 17:10

ActiveApathy


3 Answers

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();
    }
}
like image 128
ActiveApathy Avatar answered Oct 19 '22 00:10

ActiveApathy


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);
like image 40
stevyhacker Avatar answered Oct 18 '22 23:10

stevyhacker


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):

This is with Theme.AppCompat.Light theme

This is with Theme.AppCompat

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, ..):

  • mr_ic_media_route_disabled_holo_dark.png
  • mr_ic_media_route_off_holo_dark.png
  • mr_ic_media_route_on_0_holo_dark.png
  • mr_ic_media_route_on_1_holo_dark.png
  • mr_ic_media_route_on_2_holo_dark.png

(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.

like image 8
Ali Naddaf Avatar answered Oct 18 '22 23:10

Ali Naddaf