2013-05-16 12 views
19

Ich machte meine benutzerdefinierte Komponente nur einige TextViews zusammen. Jetzt möchte ich in der Lage sein, meine individuelle Steuerung init direkt aus dem Code, Text vorbei Größen unabhängig für jede der TV-So lesen Sie benutzerdefinierte Dimension Attribut von Java-Code

Meine Attribute Definition:

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

Beispiel Initialisierung der Komponente:

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

Wie ich versuche, diese Attribute im Konstruktor der Komponente zu lesen:

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

Problem: Nach der Erstellung sind alle meine Werte immer noch null. 40sp ist genau mein gewünschter Wert.

Antwort

46

ein paar Dinge zu sagen:

  • zuerst müssen Sie eine XML-Namensraum Deklarationszeile an der Spitze Ihres xml, genau in der gleichen Art und Weise, wie Sie mit Android Xmlns tun: xmlns: foo = "http : //schemas.android.com/apk/res-auto“
  • dann müssen Sie valueTextSize mit xmlns Präfix: foo: valueTextSize = "40SP"

danach, es ist nicht eine sehr gute Idee Um eine Zeichenfolge zu bekommen, bietet Android eine leistungsfähigere Lösung, um mit Dimensionen umzugehen:

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

dann gibt es einige Feinheiten:

  • für eine Farbe oder ein textpaint, können Sie diesen Wert wie: paint.setTextSize(unitTextSize):
  • für eine Textview, der obige Ansatz scheitern würde, und Sie haben eine Überlast von setText zu verwenden, um das korrekte Ergebnis zu erhalten: textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, unitTextSize);

der Unterschied kommt, was „raw Pixel“ (unskaliert nach Dichte, nur roh) aufgerufen wird und „skalierten pi xels "(das Gegenteil).

+0

vor allem - vielen Dank für die Lösung meines Problems. Was ist der beste Weg, um den Dimensionswert an TextView innerhalb der Verbundkomponente zu übergeben? – piotrpo

+0

Die Art und Weise, wie Sie es tun: Verwenden Sie ein benutzerdefiniertes Attribut, rufen Sie es während der Erstellung der zusammengesetzten Ansicht ab und übergeben Sie es dann an Ansichten, wenn es erstellt oder aufgeblasen wird. – Snicolas

11

Für ein wenig mehr Kontext auf die akzeptierte Antwort:

attrs.xml

Stellen Sie das benutzerdefinierte Attribut mit dem dimension Format.

<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

Referenz Ihre Attribute mit xmlns:app=... und setzte sie mit app:... in Ihrem xml.

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

Custom.java

Die Werte von TypedArray mit getDimensionPixelSize beziehen. In Ihrer benutzerdefinierten Ansicht arbeiten Sie nur mit Pixeln. Siehe this answer, wenn Sie in eine andere Dimension konvertieren müssen.

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

schön und sauber. –

Verwandte Themen