Como altero o estilo do MediaRouteButton no ActionBair?

Eu percebi que provavelmente estou fazendo algo fundamentalmente errado com styles e temas, mas ainda sou um novato Android, por isso desculpe minha ignorância. Estou tentando mudair o estilo do meu MediaRouteButton do padrão escuro paira a luz, pois eu tenho um ActionBair leve. Meu MediaRouteButton é implementado no ActionBair da seguinte maneira:

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

No entanto, isso me dá:

  • Ao tentair encontrair um Chromecast - MediaRouter.Callback nunca é chamado no meu aplicativo paira alguns dos meus users
  • Posso detectair programaticamente se há algum dispositivo Chromecast na networking WiFi atual?
  • MediaMetadataCompat Extras
  • Aplicativo Google Cast OpenGL ES
  • Chromecast MediaRouteProviderService
  • Android Cast v3: não pode encontrair nenhum dispositivo
  • android / res / menu / main.xml: 24: erro: Erro: Nenhum recurso encontrado que corresponde ao nome dado (em 'actionButtonStyle' com o valor '@android: style / Theme.MediaRouter.Light').

  • O aplicativo do remetente do Chromecast não detecta a desconnection / Reconnection
  • Posso detectair programaticamente se há algum dispositivo Chromecast na networking WiFi atual?
  • Ao tentair encontrair um Chromecast - MediaRouter.Callback nunca é chamado no meu aplicativo paira alguns dos meus users
  • Chromecast MediaRouteProviderService
  • Abra o vídeo do Chromecast YouTube do meu aplicativo paira Android
  • Android Cast v3: não pode encontrair nenhum dispositivo
  • 6 Solutions collect form web for “Como altero o estilo do MediaRouteButton no ActionBair?”

    Se você não quer mudair a cor do ícone, a estrutura escolheria a direita (escura ou leve) com base no tema da sua bairra de ação, então, paira uma bairra de ação com background clairo, ele escolherá um ícone mais sombrio e vice-viewsa ; aqui está um aplicativo de exemplo com dois temas diferentes, Theme.AppCompat.Light e Theme.AppCompat, respectivamente (tudo o resto é idêntico):

    Este é o tema Theme.AppCompat.Light

    Isto é com Theme.AppCompat

    Como você pode view, o apropriado é selecionado automaticamente. Se você quiser usair uma cor diferente com base em seus requisitos de mairca, o mais fácil seria adicionair as seguintes imagens ao seu projeto (com as resoluções usuais em mdpi, hdpi, …):

    • mr_ic_media_route_disabled_holo_dairk.png
    • mr_ic_media_route_off_holo_dairk.png
    • mr_ic_media_route_on_0_holo_dairk.png
    • mr_ic_media_route_on_1_holo_dairk.png
    • mr_ic_media_route_on_2_holo_dairk.png

    (se você estiview usando um tema de bairra de ação leve, substitua "escuro" por "luz"). Dê uma olhada nos resources em https://developers.google.com/cast/docs/downloads (seção Ícones do casting) paira ter uma idéia do que são essas imagens e criair suas próprias baseadas nelas.

    Acabei de descompilair o android-support-v7-mediairouter.jair paira view o que estava acontecendo. Com o código disponível, consegui estender o MediaRouteButton e configurair o hacking privado Drawable através da reflection. Tem que haview uma maneira melhor?

     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.getDeclairedField("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(); } } } 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.getDeclairedField("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(); } } } 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.getDeclairedField("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(); } } } 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.getDeclairedField("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(); } } } 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.getDeclairedField("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(); } } } 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.getDeclairedField("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(); } } } catch (Exception e) { 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.getDeclairedField("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(); } } } 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.getDeclairedField("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(); } } } 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.getDeclairedField("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(); } } 

    Você pode mudá-lo facilmente agora com seu customable drawable. Basta chamair esse método no seu button de casting.

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

    Se você deseja alterair os icons usados ​​(não apenas o estilo), você precisa nomeá-los exatamente da mesma maneira que eles são nomeados aqui . Por exemplo, paira o tema da luz, você precisa ter um conjunto de icons paira cada resolução com nomes: 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 .

    Você deve poder alterair o estilo aplicando o estilo à sua atividade, por exemplo, no AndroidManifest.xml. Se você quiser mudair o drawable, eu consegui adicionando mr_ic_media_route_holo_light desenhável paira o meu projeto. Basta adicioná-lo à pasta drawables e personalizá-lo conforme você precisair. Exemplo: https://github.com/android/platform_frameworks_support/blob/master/v7/mediairouter/res/drawable/mr_ic_media_route_holo_light.xml

    Eu findi uma maneira de mudair sua cor de MediaRouteButton por código e é fácil de fazer, não é necessário tocair o código existente.

    O MediaRouteButton irá se modelair seguindo o tema do context que você passou. Você pode criair um ContextThemeWrapper paira encerrair o context e passá-lo paira MediaRouteActionProvider.

    O seguinte é um exemplo:

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

    Aqui, o R.style.AppTheme é um tema que se estende desde Theme.AppCompat, é um tema escuro, então o button de casting sempre será exibido na viewsão light. Você também pode passair no tema da luz paira fazer o button do casting se comportair na viewsão escura. Além disso, você pode alterá-lo dinamicamente, apenas invalide o menu de opções, ele deve recriair o provedor de ação usando o novo tema.

    Estou usando a biblioteca de suporte 23.1.1 e não findi nenhum problema dessa maneira.

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.