2010-12-14 26 views
7

Me gustaría crear un View personalizado en Android. Intenté hacerlo de la manera más simple posible y creé una clase casi vacía MyView y la usé en mi LinearLayout pero la aplicación falla al comenzar con "Forzar cierre". ¿Cómo puedo hacer una simple costumbre View? De acuerdo con Building Custom Components el View obtiene el tamaño 100x100 si no anulo onMeasure().¿Cómo crear una vista personalizada simple?

public class MyView extends View { 

    public MyView(Context context) { 
     super(context); 
    } 
} 

y lo uso en un LinearLayout con:

<view 
    class="com.example.MyView" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_weight="0.0" /> 

¿Qué estoy haciendo mal?


Si uso el constructor que sugieren itemon y la llamada correspondiente a la superclase. Luego, el "Forzar cierre" se ha ido, pero mi LinearLayout está roto, los componentes después de MyView no se muestran.

Aquí es mi main.xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical" 
    > 
<TextView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_weight="0.0" 
    android:background="#f00" 
    android:text="Hello" 
/> 
<view 
    class="com.example.MyView" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_weight="0.0" 
/> 
<TextView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_weight="0.0" 
    android:background="#00f" 
    android:text="World" 
/> 
</LinearLayout> 
+0

Puede consultar una buena muestra aquí: [http://www.sgoliver.net/blog/?p=1457](http://www.sgoliver.net/blog/?p=1457) –

+0

Tengo similiar necesidades ... tienes lo que necesitas. .share some code plz – Nepster

Respuesta

9

puede ser que usted podría definir otro método constructor de esta manera:

public MyView(Context context, AttributeSet attrs) 

el marco androide tratarán de construir la interfaz de usuario con su visión desde el constructor anterior .

+0

Gracias, eso elimina el mensaje "Forzar cierre", pero mi 'LinearLayout' está roto, el componente después no se muestra. – Jonas

+2

Tuve que anular 'onMeasure()' también. Ahora funciona genial – Jonas

9

La Guía del desarrollador de Android tiene una sección llamada Creación de componentes personalizados. Desafortunadamente, la discusión de los atributos XML solo cubre declarar el control dentro del archivo de disposición y no manejar realmente los valores dentro de la inicialización de la clase. Los pasos son los siguientes: Atributos

Declare en valores \ attrs.xml

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <declare-styleable name="MyCustomView"> 
     <attr name="android:text"/> 
     <attr name="android:textColor"/>    
     <attr name="extraInformation" format="string" /> 
    </declare-styleable> 
</resources> 

Aviso el uso de un nombre no calificado en la etiqueta de declaración-styleable. Atributos android no estándar como ExtraInformation deben tener su tipo declarado. Las etiquetas declaradas en la superclase estarán disponibles en subclases sin tener que ser redeclaradas.

Crear constructores

ya que hay dos constructores que utilizan un AttributeSet para la inicialización, es conveniente crear un método de inicialización separada para los constructores para llamar.

private void init(AttributeSet attrs){ 
    TypedArray a=getContext().obtainStyledAttributes(attrs,R.styleable.MyCustomView); 
    //Use a 
    Log.i("test",a.getString(R.styleable.MyCustomView_android_text)); 
    Log.i("test",""+a.getColor(R.styleable.MyCustomView_android_textColor, Color.BLACK)); 
    Log.i("test",a.getString(R.styleable.MyCustomView_android_extraInformation)); 
    //Don't forget this 
    a.recycle(); 
} 

R.styleable.MyCustomView es un int recurso autogenerado [], donde cada elemento es el ID de un atributo. Los atributos se generan para cada propiedad en el XML al agregar el nombre del atributo al nombre del elemento. Los atributos se pueden recuperar desde TypedArray usando varias funciones get. Si el atributo no está definido en el XML, se devuelve null. Excepto, por supuesto, si el tipo de devolución es una primitiva, en cuyo caso se devuelve el segundo argumento.

Si no desea recuperar todos los atributos, es posible crear esta matriz manualmente. La ID para los atributos estándar de Android se incluye en android.R.attr, mientras que los atributos para este proyecto están en R. attr.

int attrsWanted[]=new int[]{android.R.attr.text, R.attr.textColor}; 

Tenga en cuenta que no se debe usar nada en android.R.styleable, según este hilo se puede cambiar en el futuro. Todavía está en la documentación que es útil ver todas estas constantes en un solo lugar.

utilizarlo en un archivos de diseño tales como diseño \ main.xml Incluir la declaración de espacio de nombres

xmlns: app = "http://schemas.android.com/apk/res/com.mycompany .projectname "

en el elemento xml de nivel superior.

<com.mycompany.projectname.MyCustomView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:background="@android:color/transparent" 
    android:text="Test text" 
    android:textColor="#FFFFFF" 
app:extraInformation="My extra information"; 
/> 

Haga referencia a la vista personalizada con el nombre completo.

Android LabelView Muestra

Si quieres un ejemplo completo, mira el androide muestra la etiqueta de vista.

LabelView.java

TypedArray a=context.obtainStyledAttributes(attrs, R.styleable.LabelView); 
CharSequences=a.getString(R.styleable.LabelView_text); 
attrs.xml 

<declare-styleable name="LabelView"> 
    <attr name="text"format="string"/> 
    <attr name="textColor"format="color"/> 
    <attr name="textSize"format="dimension"/> 
</declare-styleable> 

custom_view_1.xml

<com.example.android.apis.view.LabelView 
    android:background="@drawable/blue" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    app:text="Blue"app:textSize="20dp"/> 

Este está contenido en un LinearLayout con un atributo de espacio de nombres:

xmlns: app = "http: // schemas.android.com/apk/res/com.example.android.apis "

Cuestiones relacionadas