Как изменить стиль MediaRouteButton в ActionBar?

Я понимаю, что я, вероятно, делаю что-то принципиально неправильное со стилями и темами, но я все еще немного новичок в Android, поэтому, пожалуйста, извините мое невежество. Я пытаюсь изменить стиль моего MediaRouteButton от стандартного темного до света, так как у меня есть легкий ActionBar. My 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: Ошибка: ресурс не найден, который соответствует указанному имени (в 'actionButtonStyle' со значением '@android: style/Theme.MediaRouter.Light').

Ответ 1

Если вы не хотите менять цвет значка, фреймворк выбирает правильный (темный или светлый) на основе темы вашего экрана действий, поэтому для панели действий со светлым фоном выбирает более темный значок и наоборот; вот пример приложения с двумя разными темами: 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

(если вы используете световую тему, замените "темный" на "свет" ). Взгляните на активы https://developers.google.com/cast/docs/downloads (раздел "Иконописи" ), чтобы понять, что представляют собой эти изображения, и создавать собственные на тех.

Ответ 2

Я закончил декомпиляцию android-support-v7-mediarouter.jar, чтобы узнать, что происходит. Имея доступный код, я смог расширить MediaRouteButton и установить приватный сквозной хакерский взлом. Должен быть правильный путь?

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

Ответ 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

Если вы хотите изменить используемые значки (а не только стиль), вы должны назвать их так же, как они называются здесь, Например, для легкой темы вам нужно иметь набор значков для каждого разрешения с именами: 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.

Ответ 6

Вы должны иметь возможность изменить стиль, применяя стиль к своей деятельности, например. в AndroidManifest.xml. Если вы хотите изменить drawable, мне удалось добавить 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