如何更改ActionBar中MediaRouteButton的样式?

13

我意识到我可能在样式和主题方面做错了一些基本的事情,但我仍然是一个相对不熟悉Android的新手,请原谅我的无知。我试图将我的MediaRouteButton的样式从默认的深色改为浅色,因为我有一个浅色的ActionBar。我的MediaRouteButton在ActionBar中的实现如下:

<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/menu/main.xml:24: error: Error: 找不到与给定名称匹配的资源(位于“actionButtonStyle”中,值为“@android:style/Theme.MediaRouter.Light”)。

6个回答

9
如果您不想改变图标的颜色,框架会根据您操作栏的主题选择正确的图标(深色或浅色)。因此,对于具有浅色背景的操作栏,它将选择较暗的图标,反之亦然。 这里是一个包含两个不同主题的示例应用程序,Theme.AppCompat.Light和Theme.AppCompat,其他所有内容都相同:This is with Theme.AppCompat.Light theme This is with Theme.AppCompat 可以看到,自动选择了适当的图标。 如果您希望基于品牌要求使用不同的颜色,则最简单的方法是将以下图像添加到您的项目中(在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(如果您正在使用浅色操作栏主题,请将“dark”替换为“light”)。请查看Google Cast > Sample Apps资产(节目投射图标)以了解这些图像的感觉,并根据其构建自己的图像。

如果您正在使用实心操作栏和android:actionBarWidgetTheme,并且其父级为Theme.Base.AppCompat.Light.DarkActionBar(深色操作栏),则该框架似乎无法选择正确的图标(即使CC图标也显示为深色)。请参见此问题 - Tim Malseed
1
我添加了这些图片,但它们并没有改变颜色。 - mr.icetea

8

我最终反编译了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();
    }
}

1
一定有更好的方法...你找到更好的方法了吗,还是你仍在使用这种方式? - shoke
2
不,我还在使用这个。也许当谷歌发布官方API时会有更好的方法。 - ActiveApathy
无论如何,感谢您的帮助! - shoke
按钮似乎有一些默认填充(与简单的Button实例并排显示,尺寸相同,它看起来更小)。你遇到了同样的问题吗? - Marc Plano-Lesay
你的 mr_ic_media_route_holo_light 是什么? - ono

5
现在你可以使用自定义的drawable轻松地进行更改。只需在您的cast按钮上调用此方法即可。
mediaRouteButton = (MediaRouteButton) findViewById(R.id.media_route_button);
mediaRouteButton.setRemoteIndicatorDrawable(yourDrawable);

1
如果您想更改使用的图标(不仅仅是样式),您需要将它们命名为与此处相同的方式。例如,对于浅色主题,您需要拥有每个分辨率的一组图标,名称为:ic_cast_on_light.pngic_cast_on_0_light.pngic_cast_on_1_light.pngic_cast_on_2_light.pngic_cast_disabled_light.pngic_cast_off_light.png

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,在这种方式下没有发现任何问题。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接