2010-12-14 5 views
7

Mi piacerebbe creare un custom View su Android. Ho cercato di farlo nel modo più semplice possibile e ho creato una classe quasi vuota MyView e l'ho usata nel mio LinearLayout ma l'applicazione ha esito negativo all'avvio con "Chiudi forzata". Come posso fare una semplice ordinazione View? In base allo Building Custom Components, lo View ottiene la dimensione 100x100 se non si esegue l'override di onMeasure().Come creare una semplice vista personalizzata?

public class MyView extends View { 

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

e lo uso in un LinearLayout con:

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

Che cosa sto facendo di sbagliato?


Se uso il costruttore che itemon suggeriscono e la corrispondente chiamata alla superclasse. Quindi la "chiusura forzata" è scomparsa, ma il mio LinearLayout non funziona, i componenti dopo MyView non vengono visualizzati.

Ecco il mio 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

È possibile consultare un buon esempio qui: [http://www.sgoliver.net/blog/?p=1457](http://www.sgoliver.net/blog/?p=1457) –

+0

Ho simile ha bisogno .. hai quello che ti serve. .share qualche codice plz – Nepster

risposta

9

può essere che si potrebbe definire un altro metodo di costruzione in questo modo:

public MyView(Context context, AttributeSet attrs) 

quadro Android cercare di costruire l'interfaccia utente con la vista dal costruttore sopra .

+0

Grazie, questo rimuove il messaggio "Force Close", ma il mio 'LinearLayout' è rotto, il componente dopo non viene mostrato. – Jonas

+2

Ho dovuto anche sovrascrivere 'onMeasure()'. Ora funziona alla grande. – Jonas

9

La Guida per gli sviluppatori Android ha una sezione denominata Creazione di componenti personalizzati. Sfortunatamente, la discussione degli attributi XML copre solo la dichiarazione del controllo all'interno del file di layout e non la gestione effettiva dei valori all'interno dell'inizializzazione della classe. I passi sono i seguenti: attributi

Declare in valori \ 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> 

Avviso l'uso di un nome non qualificato nel tag dichiarare-styleable. Gli attributi Android non standard come extraInformation devono essere dichiarati. I tag dichiarati nella superclasse saranno disponibili in sottoclassi senza dover essere dichiarati nuovamente.

Creare costruttori

Poiché ci sono due costruttori che utilizzano un AttributeSet per l'inizializzazione, è conveniente per creare un metodo di inizializzazione separata per i costruttori di chiamare.

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 è un int [] risorsa autogenerated dove ogni elemento è l'ID di un attributo. Gli attributi vengono generati per ogni proprietà nell'XML aggiungendo il nome dell'attributo al nome dell'elemento. Gli attributi possono quindi essere recuperati da TypedArray usando varie funzioni get. Se l'attributo non è definito nell'XML, viene restituito null. Tranne, ovviamente, se il tipo di ritorno è un primitivo, nel qual caso viene restituito il secondo argomento.

Se non si desidera recuperare tutti gli attributi, è possibile creare manualmente questo array. L'ID per gli attributi Android standard è incluso in Android.R.attr, mentre gli attributi per questo progetto sono in R. attr.

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

Si prega di notare che non si dovrebbe usare qualsiasi cosa in android.R.styleable, come da questa discussione potrebbe cambiare in futuro. È ancora nella documentazione come per vedere tutte queste costanti in un posto è utile.

utilizzarlo in un file di layout, come il layout \ main.xml Includere la dichiarazione dello spazio dei nomi

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

nell'elemento xml di livello superiore.

<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"; 
/> 

Fare riferimento alla vista personalizzata utilizzando il nome completo.

LabelView Android Esempio

Se volete un esempio completo, guardare il campione di Android vista dell'etichetta.

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"/> 

Questo è contenuto in un LinearLayout con un attributo namespace:

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