Comment lire l'attribut de dimension Personnalisé du code java

j'ai fait mon composant personnalisé en assemblant quelques TextViews. Maintenant, je veux être en mesure d'initialiser mon contrôle personnalisé directement à partir du code, en passant des tailles de texte indépendamment pour chacun de DE LA TV

Mes attributs définition:

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

exemple d'initialisation du composant:

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

Comment j'essaie de lire les attributs du composant constructeur:

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

Problème: Après la création, toutes mes valeurs sont toujours nulles. 40sp est exactement ma valeur souhaitée.

21
demandé sur piotrpo 2013-05-17 00:35:08

2 réponses

A peu de choses à dire :

  • tout d'abord, vous avez besoin d'une ligne de déclaration d'espace de nom xml en haut de votre xml, exactement de la même manière que vous le faites avec android xmlns : xmlns: foo = "http://schemas.android.com/apk/res-auto"
  • alors vous devez préfixer valueTextSize avec votre xmlns: foo: valueTextSize= "40sp"

après cela, ce n'est pas une très bonne idée d'obtenir une chaîne, android offre une solution plus puissante pour traiter les dimensions :

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

ensuite, il y a quelques petites subtilités :

  • pour une peinture, ou un textpaint, vous pouvez cette valeur est : paint.setTextSize(unitTextSize):
  • pour un textview, l'approche ci-dessus échouerait, et vous devez utiliser une surcharge de setText pour obtenir le bon résultat:textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, unitTextSize);

la différence vient de ce qu'on appelle les "pixels raw" (dévissalisés selon la densité, juste raw) et les "pixels scaled" (l'opposé).

50
répondu Snicolas 2013-11-16 10:19:18

Pour un peu plus de contexte pour la accepté de répondre:

attrs.xml

Définir l'attribut personnalisé avec le 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>

activité.xml

référez vos attributs avec xmlns:app=... et les mettre dans votre xml 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

Obtenir les valeurs à partir du TypedArray en utilisant getDimensionPixelSize. Dans votre vue personnalisée il suffit de travailler avec des pixels. Voir cette réponse si vous devez vous convertir à une autre dimension.

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

    // ...
}
15
répondu Suragch 2017-05-23 12:25:19