studio programacion móviles libros libro desarrollo desarrollar curso aprende aplicaciones android android-layout android-resources

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