2016-01-19 15 views
7

Sto preparando i drawable per la mia applicazione. Ho un sacco di radiobutton, che vengono visualizzati come immagini con frame opzionale (quando selezionato). Si guarda disegnabili come la seguente:Riutilizzo di parti di Drawable su Android

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:state_checked="true"> 
     <layer-list> 
      <item> 
       <shape android:shape="rectangle"> 
        <solid android:color="@color/colorPrimary" /> 
       </shape> 
      </item> 

      <item> 
       <inset android:insetTop="@dimen/selectionBorderSize" 
        android:insetLeft="@dimen/selectionBorderSize" 
        android:insetRight="@dimen/selectionBorderSize" 
        android:insetBottom="@dimen/selectionBorderSize"> 
        <layer-list> 
         <item> 
          <shape android:shape="rectangle"> 
           <solid android:color="#ffffff"></solid> 
          </shape> 
         </item> 
         <item> 
          <bitmap android:src="@drawable/sharp7" > 
           <padding android:bottom="@dimen/selectionBorderSize" 
            android:top="@dimen/selectionBorderSize" 
            android:left="@dimen/selectionBorderSize" 
            android:right="@dimen/selectionBorderSize" /> 
          </bitmap> 
         </item> 
        </layer-list> 
       </inset> 
      </item> 
     </layer-list> 
    </item> 

    <item android:state_checked="false"> 
     <layer-list> 
      <item> 
       <shape android:shape="rectangle"> 
        <solid android:color="#ffffff" /> 
       </shape> 
      </item> 

      <item> 
       <inset android:insetTop="@dimen/selectionBorderSize" 
        android:insetLeft="@dimen/selectionBorderSize" 
        android:insetRight="@dimen/selectionBorderSize" 
        android:insetBottom="@dimen/selectionBorderSize"> 
        <layer-list> 
         <item> 
          <shape android:shape="rectangle"> 
           <solid android:color="#ffffff"></solid> 
          </shape> 
         </item> 
         <item> 
          <bitmap android:src="@drawable/sharp7" > 
           <padding android:bottom="@dimen/selectionBorderSize" 
            android:top="@dimen/selectionBorderSize" 
            android:left="@dimen/selectionBorderSize" 
            android:right="@dimen/selectionBorderSize" /> 
          </bitmap> 
         </item> 
        </layer-list> 
       </inset> 
      </item> 
     </layer-list> 
    </item> 

    <item> 
     <shape android:shape="rectangle"> 
      <solid android:color="#ffffff" /> 
     </shape> 
    </item> 
</selector> 

un altro:

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:state_checked="true"> 
     <layer-list> 
      <item> 
       <shape android:shape="rectangle"> 
        <solid android:color="@color/colorPrimary" /> 
       </shape> 
      </item> 

      <item> 
       <inset android:insetTop="@dimen/selectionBorderSize" 
        android:insetLeft="@dimen/selectionBorderSize" 
        android:insetRight="@dimen/selectionBorderSize" 
        android:insetBottom="@dimen/selectionBorderSize"> 
        <layer-list> 
         <item> 
          <shape android:shape="rectangle"> 
           <solid android:color="#ffffff"></solid> 
          </shape> 
         </item> 
         <item> 
          <bitmap android:src="@drawable/sharp6" > 
           <padding android:bottom="@dimen/selectionBorderSize" 
            android:top="@dimen/selectionBorderSize" 
            android:left="@dimen/selectionBorderSize" 
            android:right="@dimen/selectionBorderSize" /> 
          </bitmap> 
         </item> 
        </layer-list> 
       </inset> 
      </item> 
     </layer-list> 
    </item> 

    <item android:state_checked="false"> 
     <layer-list> 
      <item> 
       <shape android:shape="rectangle"> 
        <solid android:color="#ffffff" /> 
       </shape> 
      </item> 

      <item> 
       <inset android:insetTop="@dimen/selectionBorderSize" 
        android:insetLeft="@dimen/selectionBorderSize" 
        android:insetRight="@dimen/selectionBorderSize" 
        android:insetBottom="@dimen/selectionBorderSize"> 
        <layer-list> 
         <item> 
          <shape android:shape="rectangle"> 
           <solid android:color="#ffffff"></solid> 
          </shape> 
         </item> 
         <item> 
          <bitmap android:src="@drawable/sharp6" > 
           <padding android:bottom="@dimen/selectionBorderSize" 
            android:top="@dimen/selectionBorderSize" 
            android:left="@dimen/selectionBorderSize" 
            android:right="@dimen/selectionBorderSize" /> 
          </bitmap> 
         </item> 
        </layer-list> 
       </inset> 
      </item> 
     </layer-list> 
    </item> 

    <item> 
     <shape android:shape="rectangle"> 
      <solid android:color="#ffffff" /> 
     </shape> 
    </item> 
</selector> 

Se non si vuole giocare "trovare 2 differenze", l'unica cosa che cambia è l'immagine in <bitmap> tag.

Mi sento intere WET qui. C'è un modo per riutilizzare parte di questo drawable?

WET, ad es. non DRY

risposta

6

In breve: non ci sono parametri per i drawable XML, quindi potrebbe risultare un po 'complicato.

solito vorrei provare a separare tutti i singoli <item> contenuti in file separati disegnabili e poi loro sono con <item android:drawable="..." />. Questi possono poi essere riutilizzati in altri drawable.

Per esempio si potrebbe spostare la seguente voce in un file separato:

<item> 
    <shape android:shape="rectangle"> 
     <solid android:color="#ffffff" /> 
    </shape> 
</item> 

Quindi è possibile includere (riutilizzo) ovunque sia necessario:

<item android:drawable="@drawable/shared_drawable" /> 

Nel tuo caso tuttavia, è possibile risparmiare solo il 10% utilizzando questo approccio poiché gli elementi <bitmap> sono nascosti in profondità nella gerarchia.


Un altro approccio un po 'esotico consisterebbe nell'utilizzare un'attività Gradle per generare più oggetti estraibili XML da un singolo modello disegnabile. Questo ovviamente richiede che tu usi rispettivamente Gradle o Android Studio.

È possibile inserire il file estraibile nella cartella /res/raw (o qualsiasi altra cartella che non causi problemi). Chiamerò questo file modello XML drawable_template.xml come indicato di seguito. In questo file usiamo una variabile di modello Groovy ${bitmapdrawable} come segnaposto per il nome del vostro drawable bitmap attuale:

... 
    <item> 
     <bitmap android:src="@drawable/${bitmapdrawable}"><!-- placeholder for gradle --> 
      ... 
     </bitmap> 
    </item> 
... 

Ora abbiamo bisogno di definire un compito Gradle per copiare il modello drawable alla cartella attuale /res/drawable con i drawable bitmap desiderati incluso:

def drawablesToGenerate = ['sharp5', 'sharp6', 'sharp7', 'sharp8'] // bitmap names 
task drawableTemplate << { 
    drawablesToGenerate.each { drawableName -> // for each drawable 
     copy { 
      println("copy template for ${drawableName}") 
      from 'src/main/res/raw' // source folder 
      into 'src/main/res/drawable' // target folder 
      include 'drawable_template.xml' // template file 
      // rename file to final drawable 
      rename('drawable_template.xml', "drawable_gen_${drawableName}.xml") 
      expand(bitmapdrawable: "${drawableName}") 
     } 
    } 
} 
preBuild.dependsOn drawableTemplate 

Questo script può essere messo in build.gradle del file (del modulo) dell'app.

Ora i drawable finali con le diverse bitmap incluse vengono generati da un singolo file di modello in fase di compilazione. Hanno il nome drawable_gen_sharpX.xml e possono essere usati come normali drawable.