2013-10-09 61 views
11

我意识到我可能做了一些根本性的风格和主题错误,但我仍然是一个Android新手,所以请原谅我的无知。我试图将我的MediaRouteButton的样式从默认的黑暗更改为明亮,因为我有一个轻量级的ActionBar。我MediaRouteButton在动作条实施如下:如何更改ActionBar中MediaRouteButton的样式?

<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"/> 

然而,这给了我:

的Android/RES /菜单/ main.xml中:24:错误:错误:没有资源发现匹配给定名称(在'actionButtonStyle'值'@android:style/Theme.MediaRouter.Light')。

回答

7

如果你不想改变图标的​​颜色,框架将选择合适的一个基于你的动作条的主题(深色或浅色),因此对于光的背景的动作条,它会选择一个较暗的图标,反之亦然;这里有两个不同的主题,分别Theme.AppCompat.Light和Theme.AppCompat,一个示例应用程序(一切是相同的):

This is with Theme.AppCompat.Light theme

This is with Theme.AppCompat

正如你所看到的,一个合适的被自动选择。如果你想使用基于你的品牌要求不同的颜色,最简单的是将以下图片添加到您的项目(以下MDPI平常决议,华电国际,..):

  • 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

(如果您使用的是轻型操作栏主题,请将“黑色”替换为“灯光”)。看看https://developers.google.com/cast/docs/downloads(部分Cast Icons)的资产,以便了解这些图像是什么,并根据这些图像构建自己的图像。

+0

如果你正在使用一个可靠的操作栏和'':Theme.Base.AppCompat.Light.DarkActionBar'的一个父'android:actionBarWidgetTheme',那么该框架似乎不会选择正确的图标黑暗的动作条,但CC图标也显示黑暗)。看到[这个问题](http://stackoverflow.com/questions/24688598/styling-chromecast-mediaroute-button) –

+0

我添加了这些图像,但它确实改变了颜色。 –

7

我结束了反编译android-support-v7-mediarouter.jar,看看发生了什么。通过使用代码,我可以扩展MediaRouteButton并通过反射黑客设置私有Drawable。必须有更好的方法吗?

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(); 
    } 
} 
+0

必须有一个更好的方法......你有没有设法找到一个更好的方法,或者这是你仍然使用的方式? – clu

+1

没有。我仍然在使用它。也许Google在发布官方API时会有更好的方式。 – ActiveApathy

+0

感谢您的帮助! – clu

1

我找到了一种方法来通过代码更改MediaRouteButton的颜色,并且很容易完成,无需触摸现有代码。

MediaRouteButton将根据您传递的上下文主题自行设计风格。您可以创建一个ContextThemeWrapper来包装上下文,然后将其传递给MediaRouteActionProvider。

下面是一个例子:

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

这里R.style.AppTheme是从Theme.AppCompat延伸的主题,这是一个黑暗的主题所以剧组按钮会始终显示在轻型版本。您还可以传入轻量级主题以使投射按钮在黑暗版本中表现得更好。您也可以动态更改它,只需使选项菜单无效,就应该使用新主题重新创建操作提供程序。

我正在使用支持库23.1.1,并没有以这种方式发现任何问题。

1

如果你想改变使用的图标(不仅仅是样式),你需要命名为here。例如,对于轻量级主题,您需要为名称中的每个分辨率设置一组图标: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

2

您可以使用自定义绘图工具轻松更改它。 只需在您的投射按钮上调用此方法即可。

mediaRouteButton = (MediaRouteButton) findViewById(R.id.media_route_button); 
mediaRouteButton.setRemoteIndicatorDrawable(yourDrawable);