7

Supponiamo che sto facendo alcune nuove viste con attributi stilizzabili. Dichiaro di loro questa convenzione (questo è how the documentation says to do it:Qual è il punto di dichiarare-stilizzabile?

<?xml version="1.0" encoding="utf-8"?> 
<resources> 

    <declare-styleable name="TriangleView"> 
     <attr name="direction"> 
      <enum name="NE" value="0" /> 
      <enum name="NW" value="1" /> 
      <enum name="SW" value="2" /> 
      <enum name="SE" value="3" /> 
     </attr> 
    </declare-styleable> 

    <declare-styleable name="BannerView"> 
     <attr name="direction"> 
      <enum name="NE" value="0" /> 
      <enum name="NW" value="1" /> 
      <enum name="SW" value="2" /> 
      <enum name="SE" value="3" /> 
     </attr> 
     <attr name="thickness" format="dimension" /> 
    </declare-styleable> 
</resources> 

Tuttavia, questo non funziona perché tutti gli attributi sono apparentemente nello stesso namespace, ed ottengo l'errore Error: Attribute "direction" has already been defined

Quindi a quanto pare devo muovere. gli attributi apparentemente duplicati di fuori del <declare-styleable> in questo modo:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 


    <attr name="direction"> 
     <enum name="NE" value="0" /> 
     <enum name="NW" value="1" /> 
     <enum name="SW" value="2" /> 
     <enum name="SE" value="3" /> 
    </attr> 

    <declare-styleable name="BannerView"> 
     <attr name="thickness" format="dimension" /> 
    </declare-styleable> 
</resources> 

Ma questo pone due domande:

  1. Se funziona, qual è esattamente il punto di <declare-styleable>?
  2. Cosa fare se si desidera che l'attributo si comporti in modo diverso nelle diverse visualizzazioni? Ad esempio se la direzione di BannerView può essere solo up o down.

risposta

15

Che cosa è esattamente il punto di <declare-styleable>?

<declare-stylable> tag consentono di dichiarare gli attributi per le visualizzazioni personalizzate che è possibile quindi impostare per tali visualizzazioni in xml. Ci sono davvero 3 parti di utilizzare l'attributo:

  1. dichiarare un <attr> all'interno di un tag <declare-stylable>.
  2. Definire uno spazio dei nomi personalizzato nel layout xml che punta al nome del pacchetto dell'app (ad esempio app). Utilizza l'attributo personalizzato nel tuo layout (ad esempio app:direction="NW").
  3. Nella visualizzazione personalizzata, sovrascrivere i costruttori con un parametro AttributeSet, ottenere un TypedArray e leggere gli attributi personalizzati, se presenti, e quindi all'interno del costruttore dire alla vista come utilizzare tali attributi in modo appropriato.

Cosa succede se l'attributo si comporta in modo diverso in punti di vista diversi? Ad esempio se la direzione di BannerView può essere solo verso l'alto o verso il basso.

provare qualcosa di simile:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 

    <attr name="direction"> 
     <enum name="NE" value="0" /> 
     <enum name="NW" value="1" /> 
     <enum name="SW" value="2" /> 
     <enum name="SE" value="3" /> 
    </attr> 

    <declare-styleable name="TriangleView"> 
     <attr name="direction" /> 
    </declare-styleable> 

    <declare-styleable name="BannerView"> 
     <attr name="direction" /> 
     <attr name="thickness" format="dimension" /> 
    </declare-styleable> 
</resources> 

Quando si crea il layout XML per TriangleView o BannerView, è possibile utilizzare l'esempio app:direction="NW" per entrambi. Nei costruttori con AttributeSet in TriangleView o BannerView, gli attributi avranno lo stesso formato come l'originale, ma ciò che si fai con quel valore dipende l'implementazione dei costruttori in ogni rispettivo vista (può essere lo stesso o diverso per entrambi).

Se si desidera che gli attributi siano definiti differentemente (es.diverso "formato" o "enum") per viste diverse, quindi devi creare attributi diversi con nomi diversi.

+0

Impressionante, in realtà mi ha aiutato anche per attr definito nell'app-compat lib! Quindi è fondamentalmente, se un attr è già definito, dovrebbe essere usato in declare-styleable, senza provare a sovrascrivere il formato. Cool cool cool. – Redwarp