2013-10-09 25 views
11

Mi rendo conto che probabilmente sto facendo qualcosa di fondamentalmente sbagliato con stili e temi, ma sono ancora un po 'un principiante di Android quindi scusate la mia ignoranza. Sto cercando di cambiare lo stile del mio MediaRouteButton dal buio alla luce di default dato che ho un Light ActionBar. Il mio MediaRouteButton è implementato nel ActionBar come segue:Come si modifica lo stile di MediaRouteButton in ActionBar?

Android/res/menu/main.xml:: 24: errore: Errore: Nessun risorsa trovato che corrisponde alla data

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

Tuttavia, questo mi dà name (in 'actionButtonStyle' con valore '@android: style/Theme.MediaRouter.Light').

risposta

7

Se non si desidera modificare il colore dell'icona, quadro avrebbe scelto quella giusta (chiaro o scuro) sulla base del tema del vostro ActionBar, quindi per un ActionBar con sfondo chiaro, lo farà scegliere un'icona più scura e viceversa; ecco un app campione con due temi diversi, rispettivamente Theme.AppCompat.Light e Theme.AppCompat, (tutto il resto è identico):

This is with Theme.AppCompat.Light theme

This is with Theme.AppCompat

Come si può vedere, quella appropriata è selezionato automaticamente. Se si desidera utilizzare un colore diverso in base alle vostre esigenze di branding, il modo più semplice sarebbe quella di aggiungere le seguenti immagini per il vostro progetto (con usuali risoluzioni sotto 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

(se si utilizza un tema di barra di luce, sostituire "scuro" con "luce"). Dai uno sguardo alle risorse a https://developers.google.com/cast/docs/downloads (sezione Cast Icons) per avere un'idea di cosa sono queste immagini e costruisci le tue basandoti su quelle.

+0

Il framework non sembra scegliere le icone corrette se stai usando una barra di azione solida e' android: actionBarWidgetTheme' con un genitore di 'Theme.Base.AppCompat.Light.DarkActionBar' (a barra di azione scura, tuttavia l'icona CC si presenta anche scura). Vedi [questa domanda] (http://stackoverflow.com/questions/24688598/styling-chromecast-mediaroute-button) –

+0

Ho aggiunto queste immagini ma cambia colore. –

7

Ho finito per decompilare android-support-v7-mediarouter.jar per vedere cosa stava succedendo. Con il codice disponibile sono stato in grado di estendere MediaRouteButton e impostare il Drawable privato tramite reflection hacking. Ci deve essere un modo migliore, giusto?

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

Ci deve essere un modo migliore ... Sei riuscito a trovare un modo migliore, o è così che stai ancora usando? – clu

+1

No. Sto ancora usando questo. Forse ci sarà un modo migliore quando Google rilascia l'API ufficiale. – ActiveApathy

+0

Grazie comunque per l'aiuto! – clu

1

Ho trovato un modo per modificare il colore di MediaRouteButton in base al codice, ed è facile da eseguire, non è necessario toccare il codice esistente.

MediaRouteButton si modellerà seguendo il tema del contesto passato. È possibile creare ContextThemeWrapper per racchiudere il contesto e quindi passarlo a MediaRouteActionProvider.

seguente è un esempio:

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

Qui il R.style.AppTheme è un tema che si estende da Theme.AppCompat, si tratta di un tema scuro in modo che il pulsante di cast sarà sempre mostrare in versione light. Puoi anche passare il tema della luce per fare in modo che il pulsante cast si comporti nella versione dark. Inoltre è possibile modificarlo in modo dinamico, basta invalidare il menu delle opzioni, dovrebbe ricreare il fornitore di azioni utilizzando il nuovo tema.

Sto utilizzando la libreria di supporto 23.1.1 e non ho riscontrato alcun problema in questo modo.

1

Se si desidera modificare le icone utilizzate (non solo lo stile), è necessario denominarle nello stesso modo in cui sono denominate here. Ad esempio, per il tema della luce, è necessario disporre di un set di icone per ogni risoluzione con nomi: 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.

2

Ora puoi cambiarlo facilmente con il tuo drawable personalizzato. Basta chiamare questo metodo sul pulsante Cast.

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