3

I can't seem to get the MediaRoute button to show up as 'white' in my solid ActionBar.

My question is this: How can we style the MediaRoute button light or dark, without changing drawable names?

Looking at a similar question here: How do I change the style of the MediaRouteButton in the ActionBar? the accepted solution is just to use your own set of MediaRoute drawables, and swap the names light<>dark.

For my app, I have 3 distinct styles: light-ActionBar, dark-ActionBar, and light solid-ActionBar. I can't simply swap the drawable names, as I need both dark and light to display correctly for the first two themes. In order to display the solid actionbar contents correctly, I'm doing something like this: (Following example found here: http://www.jayway.com/2014/06/02/android-theming-the-actionbar/)

//Parent Light.DarkActionBar should give white ActionBar icons
<style name="AppTheme.Solid.Light" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:actionBarStyle">@style/Widget.Solid.ActionBar</item>
    <item name="android:actionBarWidgetTheme">@style/ActionBarWidget</item>
    .
    .

//Make the ActionBar solid, but need to use 'inverse' to keep the icons/text white
<style name="Widget.Solid.ActionBar" parent="Widget.AppCompat.Light.ActionBar.Solid.Inverse">
.
.

//**** THE ISSUE IS CAUSED BY USING THE FOLLOWING
//Make the ActionBar dropdown spinner items use the correct (white) theme as well
<style name="ActionBarWidget" parent="Theme.AppCompat.Light.DarkActionBar">
.
.

The ActionBarWidget theme is necessary to ensure the ActionBar overflow icon dropdown menu background shows up as white instead of black. However, it causes the MediaRoute button to change to it's dark-theme drawables, which does not suit.

I've tried overriding Widget.MediaRouter.MediaRouteButton and forcing <item name="externalRouteEnabledDrawable">@drawable/mr_ic_media_route_holo_dark</item>, but nothing I do makes a difference.

How can we style the MediaRoute button light or dark, without changing drawable names? Is there a simple style to override where we can set our own MediaRoute drawables?

Community
  • 1
  • 1
Tim Malseed
  • 6,003
  • 6
  • 48
  • 66

2 Answers2

1

Try the following:

menu.xml:

<item
    android:id="@+id/media_route_menu_item"
    android:title="@string/media_route_menu_title"
    app:actionProviderClass="android.support.v7.app.MediaRouteActionProvider"
    app:actionViewClass="com.???.MediaRouteButtonHoloDark"
    app:showAsAction="always" />

MediaRouteButtonHoloDark:

public class MediaRouteButtonHoloDark extends MediaRouteButton {

    public MediaRouteButtonHoloDark( Context context ) {
        this( context, null );
    }

    public MediaRouteButtonHoloDark( Context context, AttributeSet attrs ) {
        this( context, attrs, android.support.v7.mediarouter.R.attr.mediaRouteButtonStyle ); 
    }

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

    private static Context getThemedContext( Context context ) {
        context = new ContextThemeWrapper( context, android.support.v7.appcompat.R.style.Theme_AppCompat );
        return new ContextThemeWrapper( context,  android.support.v7.mediarouter.R.style.Theme_MediaRouter );

    }   
}

And somewhere in your code:

...
MenuItem mediaRouteMenuItem = menu.findItem( R.id.media_route_menu_item );      
MediaRouteButton mediaRouteButton = (MediaRouteButton) MenuItemCompat.getActionView( mediaRouteMenuItem ); 
mediaRouteButton.setRouteSelector( mMediaRouteSelector );
...
braintrapp
  • 748
  • 9
  • 11
  • Thanks for the answer. I'm having trouble using this with the CastCompanionLibrary. It seems that settings a custom actionViewClass causes a NullPointerException with the CCL. I'm debugging it and I haven't been able to fix it. If can confirm this is working I'll accept the answer. – Tim Malseed Aug 18 '14 at 10:01
0

I got a similar problem with the null pointer exception also. I don't use the CastCompanionLibrary, but I solved it like this:

1.) Do not use the app:actionProviderClass in your menu definition.

<item
   android:id="@+id/media_route_menu_item"
   android:title="@string/media_route_menu_title"
   app:actionViewClass="com.???.MediaRouteButtonHoloDark"
   app:showAsAction="always" />

2.) Search for the place where your code or the CCL tries to get the ActionProvider and if no ActionProvider is found then just search for the ActionView with the MediaRouteButton. Like this:

....
MenuItem mediaRouteMenuItem = menu.findItem( R.id.media_route_menu_item );

MediaRouteActionProvider mediaRouteActionProvider = (MediaRouteActionProvider) MenuItemCompat.getActionProvider( mediaRouteMenuItem );
if (null!=mediaRouteActionProvider) {
    Log.i( TAG, "MediaRouteActionProvider found" );
    mediaRouteActionProvider.setRouteSelector( mMediaRouteSelector );
    return;
}

MediaRouteButton mediaRouteButton = (MediaRouteButton) MenuItemCompat.getActionView( mediaRouteMenuItem );
if (null!=mediaRouteButton) {
    Log.i( TAG, "MediaRouteButton found" );
    mediaRouteButton.setRouteSelector( mMediaRouteSelector );
    return;
}
....

I hope, this helps.

braintrapp
  • 748
  • 9
  • 11