móviles - manual de programacion android pdf
Cómo leer el atributo de dimensión personalizado desde el código java (2)
Hice mi componente personalizado simplemente poniendo unas pocas vistas de texto juntas. Ahora quiero poder iniciar mi control personalizado directamente desde el código, pasando tamaños de texto independientemente para cada uno de los televisores
Definición de mis atributos:
<resources>
<declare-styleable name="BasicGauge">
<attr name="valueTextSize" format="dimension" />
<attr name="titleTextSize" format="dimension" />
<attr name="unitsTextSize" format="dimension" />
</declare-styleable>
</resources>
Ejemplo de inicialización del 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>
Cómo trato de leer esos atributos en el constructor 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: Después de la creación, todos mis valores siguen siendo nulos. 40sp es exactamente mi valor deseado.
Algunas cosas para decir:
- primero necesita una línea de declaración de espacio de nombre xml en la parte superior de su xml, exactamente de la misma manera que lo hace con xmlns de android: xmlns: foo = "http://schemas.android.com/apk/res-auto"
- entonces necesitas el prefijo valueTextSize con tus xmlns: foo: valueTextSize = "40sp"
Después de eso, no es una buena idea obtener una cadena, Android ofrece una solución más poderosa para lidiar con las dimensiones:
int unitsTextSize = typedArray.getDimensionPixelSize(R.styleable.BasicGauge_unitsTextSize, textSize);
entonces hay algunas sutilezas:
- para una pintura, o una pintura de texto, puede este valor como está:
paint.setTextSize(unitTextSize):
- para una vista de texto, el enfoque anterior fallaría, y debe utilizar una sobrecarga de setText para obtener el resultado correcto:
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, unitTextSize);
La diferencia proviene de lo que se denomina "píxeles sin procesar" (sin escalar según la densidad, solo sin procesar) y "píxeles con escala" (lo contrario).
Para un poco más de contexto a la respuesta aceptada:
attrs.xml
Establecer el atributo personalizado con el formato de dimension
.
<resources>
<declare-styleable name="CustomView">
<attr name="valueTextSize" format="dimension" />
<attr name="titleTextSize" format="dimension" />
<attr name="unitsTextSize" format="dimension" />
</declare-styleable>
</resources>
actividad.xml
Haga referencia a sus atributos con xmlns:app=...
y configúrelos en su xml con la 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
Obtenga los valores de TypedArray usando getDimensionPixelSize
. Dentro de su vista personalizada solo trabaje con píxeles. Vea esta respuesta si necesita convertir a una dimensión diferente.
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();
}
}
// ...
}