2013-05-16 17 views
19

Ho creato il mio componente personalizzato inserendo solo alcune Immagini di testo. Ora voglio essere in grado di init il mio controllo personalizzato direttamente dal codice, passando dimensione del testo in modo indipendente per ciascuno dei dei TV definizioneCome leggere l'attributo di dimensione personalizzato dal codice java

miei attributi:

<resources> 
    <declare-styleable name="BasicGauge"> 
     <attr name="valueTextSize" format="dimension" /> 
     <attr name="titleTextSize" format="dimension" /> 
     <attr name="unitsTextSize" format="dimension" /> 
    </declare-styleable> 
</resources> 

inizializzazione Esempio di componente:

<pl.com.digita.BikeComputerUi.customviews.BasicGauge 
    android:id="@+id/basicGauge1" 
    android:layout_width="0dp" 
    android:layout_height="wrap_content" 
    android:layout_weight="1" 
    android:padding="10dp" 
    valueTextSize="40sp"> 

</pl.com.digita.BikeComputerUi.customviews.BasicGauge> 

Come provo a leggere quegli attributi nel costruttore del componente:

final int N = typedArray.getIndexCount(); 
for (int i = 0; i < N; i++) { 
    int attribute = typedArray.getIndex(i); 
    switch (attribute) { 
     case R.styleable.BasicGauge_valueTextSize: 
      valueTextSize = typedArray.getString(attribute); 
      break; 
     case R.styleable.BasicGauge_titleTextSize: 
      titleTextSize = typedArray.getString(attribute); 
      break; 
     case R.styleable.BasicGauge_unitsTextSize: 
      unitsTextSize = typedArray.getString(attribute); 
      break; 
    } 
    typedArray.recycle(); 
} 

Problema: Dopo la creazione, tutti i miei valori sono ancora nulli. 40sp è esattamente il mio valore desiderato.

risposta

46

Un paio di cose da dire:

  • prima è necessario uno spazio di riga della dichiarazione nome XML nella parte superiore del vostro xml, esattamente nello stesso modo come si fa con xmlns Android: xmlns: foo = "http : //schemas.android.com/apk/res-auto"
  • allora avete bisogno di prefisso valueTextSize con i tuoi xmlns: foo: valueTextSize = "40SP"

Dopo di che, non è una buona idea per ottenere una stringa, Android offre una soluzione più potente per gestire le dimensioni:

int unitsTextSize = typedArray.getDimensionPixelSize(R.styleable.BasicGauge_unitsTextSize, textSize); 

poi ci sono alcune sottigliezze:

  • per una vernice, o un textpaint, è possibile questo valore come è: paint.setTextSize(unitTextSize):
  • per un TextView, l'approccio di cui sopra sarebbe fallito, e si dispone di utilizzare un sovraccarico di setText per ottenere il risultato corretto: textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, unitTextSize);

la differenza deriva dalla cosiddetta "pixel" grezzi (non convertito in base alla densità, appena prima) e "pi in scala xels "(il contrario).

+0

prima di tutto, grazie per aver risolto il mio problema. Qual è il modo migliore per passare il valore della quota a TextView all'interno del componente composto? – piotrpo

+0

Il modo in cui lo fai: usa un attributo personalizzato, recuperalo durante la costruzione della vista composta, quindi passa alle viste quando viene creato o gonfiato. – Snicolas

11

Per un po 'più di contesto per la risposta accettata:

attrs.xml

Impostare l'attributo personalizzato con il formato dimension.

<resources> 
    <declare-styleable name="CustomView"> 
     <attr name="valueTextSize" format="dimension" /> 
     <attr name="titleTextSize" format="dimension" /> 
     <attr name="unitsTextSize" format="dimension" /> 
    </declare-styleable> 
</resources> 

activity.xml

riferimento tuoi attributi con xmlns:app=... e metterli in XML con app:....

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       xmlns:app="http://schemas.android.com/apk/res-auto" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent"> 

    <com.example.myproject.CustomView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     app:valueTextSize="40sp" 
     app:titleTextSize="20sp" 
     app:unitsTextSize="24sp" /> 

</RelativeLayout> 

CustomView.java

Ottenere i valori da TypedArray utilizzando getDimensionPixelSize. All'interno della tua vista personalizzata funziona solo con i pixel. Vedere this answer se è necessario convertire in una dimensione diversa.

public class CustomView extends View { 

    private float mValueTextSize; // pixels 
    private float mTitleTextSize; // pixels 
    private float mUnitsTextSize; // pixels 

    public CustomView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     TypedArray a = context.getTheme().obtainStyledAttributes(
       attrs, R.styleable.CustomView, 0, 0); 
     try { 
      mValueTextSize = a.getDimensionPixelSize(R.styleable.CustomView_valueTextSize, 0); 
      mTitleTextSize = a.getDimensionPixelSize(R.styleable.CustomView_titleTextSize, 0); 
      mUnitsTextSize = a.getDimensionPixelSize(R.styleable.CustomView_unitsTextSize, 0); 
     } finally { 
      a.recycle(); 
     } 
    } 

    // ... 
} 
+0

bello e pulito. –

Problemi correlati