【问题标题】:How do I change the style of the MediaRouteButton in the ActionBar?如何更改 ActionBar 中 MediaRouteButton 的样式?
【发布时间】:2013-10-17 04:23:55
【问题描述】:

我意识到我可能在样式和主题方面做错了什么,但我还是一个 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”)。

【问题讨论】:

    标签: android google-cast chromecast


    【解决方案1】:

    如果您不想更改图标的颜色,框架会根据您的操作栏的主题选择正确的(深色或浅色),因此对于浅色背景的操作栏,它将选择较暗的图标反之亦然;这是一个示例应用程序,有两个不同的主题,分别是 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

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

    【讨论】:

    • 如果您使用的是实心操作栏和android:actionBarWidgetTheme 的父级为Theme.Base.AppCompat.Light.DarkActionBar,框架似乎没有选择正确的图标(一个黑色的操作栏,但CC 图标显示也很黑)。见this question
    • 我添加了这些图片,但它确实改变了颜色。
    【解决方案2】:

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

    【讨论】:

    • 必须有更好的方法...您是否设法找到了更好的方法,还是您仍在使用这种方法?
    • 不。我还在用这个。或许在 Google 发布官方 API 时会有更好的方法。
    • 感谢您的帮助!
    • 按钮似乎有一些默认填充(显示在一个简单的 Button 实例旁边,大小相同,但看起来更小)。你有同样的问题吗?
    • 你是什么mr_ic_media_route_holo_light
    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

      我找到了一种通过代码更改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,这种方式没有发现任何问题。

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

          您应该能够通过将样式应用于您的活动来更改样式,例如在 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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-08-02
            • 1970-01-01
            • 2016-12-24
            • 1970-01-01
            • 2014-06-08
            • 1970-01-01
            相关资源
            最近更新 更多