Pregunta

Tengo un componente personalizado que contiene dos vistas de texto que tienen un método de establecimiento de tamaño personalizado (las dos vistas de texto son proporcionales en aproximadamente una relación 1: 2). Siendo que esta es una subclase de RelativeLayout, no tiene un atributo de tamaño de texto, pero me pregunto si es posible establecer el android:textSize atributo en la instanciación XML para este componente, y luego toma el textSize atributo del atributeset para usar con mi personalizado setSize() Método en el constructor.

He visto la técnica para hacer esto con atributos personalizados, pero ¿qué pasa si quiero obtener un atributo que ya está en el léxico de Android?

¿Fue útil?

Solución

Sí, es posible;

Supongamos que su declaración de relativeLayout (en XML) tiene un tamaño de texto definido con 14sp:

android:textSize="14sp"

En el constructor de su vista personalizada (la que toma en el AttributesET), puede recuperar los atributos del espacio de nombres de Android como tal:

String xmlProvidedSize = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "textSize");

El valor del XMLProvidedSize será algo así como este "14.0sp" y tal vez con un poco de edición de cadenas, puede extraer los números.


Otra opción para declarar su propio conjunto de atributos sería poco largo, pero también es posible.

Por lo tanto, tiene su vista personalizada y sus vistas de textos declaradas algo así:

public class MyCustomView extends RelativeLayout{

    private TextView myTextView1;
    private TextView myTextView2;

// rest of your class here

estupendo...

Ahora también debe asegurarse de que su visión personalizada anule el constructor que recibe el conjunto de atributos de la misma manera:

public MyCustomView(Context context, AttributeSet attrs){   
    super(context, attrs);
    init(attrs, context);  //nice, clean method to instantiate your TextViews// 
}

Ok, veamos ese método init () ahora:

private void init(AttributeSet attrs, Context context){
    // do your other View related stuff here //


    TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.MyCustomView);
    int xmlProvidedText1Size = a.int(R.styleable.MyCustomView_text1Size);
    int xmlProvidedText2Size = a.int(R.styleable.MyCustomView_text2Size);

    myTextView1.setTextSize(xmlProvidedText1Size);
    myTextView2.setTextSize(xmlProvidedText2Size);

    // and other stuff here //
}

Probablemente se esté preguntando de dónde se produce r.stylable.mycustomView, r.stylable.mycustomView_text1size y r.stylable.mycustomView_text2size provienen de; Permítame dar más detalles sobre ellos.

Debe declarar los nombre (s) de atributos en su archivo ATTRS.XML (en el directorio de valores) para que cuando use su vista personalizada, los valores recopilados de estos atributos se entregarán en su constructor.

Así que veamos cómo declaras estos atributos personalizados como has preguntado: aquí están todos mis attr.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyCustomView">
        <attr name="text1Size" format="integer"/>
        <attr name="text2Size" format="integer"/>
    </declare-styleable>
</resources>

Ahora puede configurar el tamaño de su TextViews en su XML, pero no sin declarar el espacio de nombres en su diseño, así es como:

<com.my.app.package.MyCustomView
    xmlns:josh="http://schemas.android.com/apk/res-auto"
    android:id="@+id/my_custom_view_id"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    josh:text1Size="15"
    josh:text2Size="30"     
    />

Preste atención cómo declaré que el espacio de nombres era "Josh" como la primera línea en el conjunto de atributos de su CustomView.

Espero que esto ayude a Josh

Otros consejos

La respuesta aceptada es un poco larga. Aquí hay una versión condensada que espero sea fácil de seguir. Para agregar un textSize atributo (o cualquier cosa que use dp/sp) A su vista personalizada, haga los siguientes pasos.

1. Cree un atributo personalizado

Crear (o agregar la siguiente sección) a attrs.xml. Nota la dimension formato.

<resources>
    <declare-styleable name="CustomView">
        <attr name="textSize" format="dimension" />
    </declare-styleable>
</resources>

2. Establezca el atributo en su diseño XML.

Tenga en cuenta la costumbre app espacio de nombres.

<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:textSize="20sp" /> 

</RelativeLayout>

3. Obtenga el valor del atributo en su vista personalizada

Tenga en cuenta el uso de getDimensionPixelSize. Dentro de su vista personalizada, solo trabaje con píxeles. Ver esta respuesta Si necesita convertir a una dimensión diferente.

public class CustomView extends View {

    private float mTextSize; // pixels

    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs, R.styleable.CustomView, 0, 0);
        try {
            mTextSize = a.getDimensionPixelSize(R.styleable.CustomView_textSize, 0);
        } finally {
            a.recycle();
        }
    }

    /**
     * @param size in SP units
     */
    public void setTextSize(int size) {
        mTextSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                size, getResources().getDisplayMetrics());
        mTextPaint.setTextSize(mTextSize);
        invalidate();
        requestLayout();
    }

    // ...
}

Notas

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top