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:错误:错误:找不到与给定名称匹配的资源(在“actionButtonStyle”处,值为“@android:style/Theme.MediaRouter.Light”)。

4

6 回答 6

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();
    }
}
于 2013-10-09T22:24:36.640 回答
8

如果您不想更改图标的颜色,框架会根据您的操作栏的主题选择正确的(深色或浅色),因此对于浅色背景的操作栏,它将选择较暗的图标,反之亦然; 这是一个示例应用程序,有两个不同的主题,分别是 Theme.AppCompat.Light 和 Theme.AppCompat(其他一切都相同):

这是 Theme.AppCompat.Light 主题

这是 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

(如果您使用的是浅色操作栏主题,请将“深色”替换为“浅色”)。查看Google Cast > Sample Apps (Cast Icons 部分)中的资产,了解这些图像是什么,并根据这些图像构建您自己的图像。

于 2014-02-21T08:28:54.870 回答
5

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

mediaRouteButton = (MediaRouteButton) findViewById(R.id.media_route_button);
mediaRouteButton.setRemoteIndicatorDrawable(yourDrawable);
于 2016-09-18T13:46:33.367 回答
1

如果您想更改使用的图标(不仅仅是样式),您需要以与此处的命名方式完全相同的方式命名它们。例如,对于浅色主题,您需要为每个分辨率设置一组图标,名称为: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

于 2016-02-12T15:48:16.513 回答
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 并没有发现任何问题。

于 2015-11-28T13:55:49.967 回答
0

您应该能够通过将样式应用于您的活动来更改样式,例如在 AndroidManifest.xml 中。如果您想更改可绘制对象,我成功地将 mr_ic_media_route_holo_light 可绘制对象添加到我的项目中。只需将其添加到 drawables 文件夹并根据需要对其进行自定义。示例:https ://github.com/android/platform_frameworks_support/blob/master/v7/mediarouter/res/drawable/mr_ic_media_route_holo_light.xml

于 2014-08-22T08:41:55.467 回答