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