xml - create - Android Custom View Constructor
custom attributes android (3)
Estoy aprendiendo sobre el uso de Vistas personalizadas a partir de lo siguiente:
http://developer.android.com/guide/topics/ui/custom-components.html#modifying
La descripción dice:
Inicialización de clase Como siempre, el super se llama primero. Además, este no es un constructor predeterminado, sino uno parametrizado. EditText se crea con estos parámetros cuando está inflado desde un archivo de diseño XML, por lo tanto, nuestro constructor necesita tomarlos y pasarlos también al constructor de la superclase.
Hay una mejor descripción? He estado tratando de descubrir cómo deberían verse los constructores y he encontrado 4 opciones posibles (ver ejemplo al final de la publicación). No estoy seguro de lo que estas 4 opciones hacen (o no), por qué debería implementarlas o qué significan los parámetros. ¿Hay una descripción de estos?
public MyCustomView()
{
super();
}
public MyCustomView(Context context)
{
super(context);
}
public MyCustomView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public MyCustomView(Context context, AttributeSet attrs, Map params)
{
super(context, attrs, params);
}
Aquí hay un patrón mi (creando un ViewGoup
personalizado aquí, pero aún):
// CustomView.java
public class CustomView extends LinearLayout {
public CustomView(Context context) {
super(context);
init(context);
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public CustomView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context ctx) {
LayoutInflater.from(ctx).inflate(R.layout.view_custom, this, true);
// extra init
}
}
y
// view_custom.xml
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Views -->
</merge>
No necesita el primero, ya que eso simplemente no funcionará.
El tercero significará que su View
personalizada se podrá utilizar a partir de archivos de diseño XML. Si no te importa eso, no lo necesitas.
El cuarto es simplemente incorrecto, AFAIK. No hay un constructor View
que tome un Map
como el tercer parámetro. Hay uno que toma un int
como el tercer parámetro, utilizado para anular el estilo predeterminado para el widget.
Tiendo a usar la sintaxis this()
para combinar estos:
public ColorMixer(Context context) {
this(context, null);
}
public ColorMixer(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ColorMixer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// real work here
}
Puede ver el resto de este código en este ejemplo de libro .
Cuando agregue su View
personalizada desde xml
como:
<com.mypack.MyView
...
/>
Necesitarás el constructor público MyView(Context context, AttributeSet attrs),
contrario, obtendrás una Exception
cuando Android
intente inflate
tu View
.
Y cuando agrega su View
desde xml
y también especifica el attribute
android:style
como:
<com.mypack.MyView
style="@styles/MyCustomStyle"
...
/>
también necesitarás el tercer constructor público MyView(Context context, AttributeSet attrs,int defStyle)
.
El tercer constructor se usa generalmente cuando extiende un estilo y lo personaliza, y luego desea establecer ese style
para una View
determinada en sus diseños.
Editar detalles
public MyView(Context context, AttributeSet attrs) {
//Called by Android if <com.mypack.MyView/> is in layout xml file without style attribute.
//So we need to call MyView(Context context, AttributeSet attrs, int defStyle)
// with R.attr.customViewStyle. Thus R.attr.customViewStyle is default style for MyView.
this(context, attrs, R.attr.customViewStyle);
}
Mira esto