2012-06-25 3 views
18

Devo creare una vista personalizzata più complessa in Android. Il layout finale dovrebbe essere simile a questo:Android: vista multipla bambini per visualizzazione personalizzata con layout esistente

<RelativeLayout> 
    <SomeView /> 
    <SomeOtherView /> 
    <!-- maybe more layout stuff here later --> 
    <LinearLayout> 
    <!-- the children --> 
    </LinearLayout> 
</RelativeLayout> 

Tuttavia, nei file XML che voglio solo che definire questo (senza definire SomeView, SomeOtherView ecc):

<MyCustomView> 
    <!-- the children --> 
</MyCustomView> 

Questo è possibile in Android, e se sì: quale sarebbe il modo più pulito per farlo? Le possibili soluzioni che mi sono venute in mente erano 'ignorare l'addView() metodi' e 'rimuovere tutti i punti di vista e aggiungerli più tardi', ma non sono sicuro da che parte andare ...

Grazie mille in anticipo per il tuo aiuto! :)

risposta

34

È assolutamente possibile e consigliato creare viste container personalizzate. Questo è ciò che Android chiamerebbe un controllo composto. Quindi:

public class MyCustomView extends RelativeLayout { 
    private LinearLayout mContentView; 

    public MyCustomView(Context context) { 
     this(context, null); 
    } 

    public MyCustomView(Context context, AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 

    public MyCustomView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     //Inflate and attach your child XML 
     LayoutInflater.from(context).inflate(R.layout.custom_layout, this); 
     //Get a reference to the layout where you want children to be placed 
     mContentView = (LinearLayout) findViewById(R.id.content); 

     //Do any more custom init you would like to access children and do setup 
    } 

    @Override 
    public void addView(View child, int index, ViewGroup.LayoutParams params) { 
     if(mContentView == null){ 
      super.addView(child, index, params); 
     } else { 
      //Forward these calls to the content view 
      mContentView.addView(child, index, params); 
     } 
    } 
} 

è possibile ignorare il maggior numero di versioni di addView() come si sente sono necessarie, ma alla fine tutti hanno chiamata indietro alla versione ho inserito nel campione. Sostituendo solo questo metodo, il framework passerà tutti i child trovati all'interno del suo tag XML in un contenitore figlio specifico.

e quindi modificare il XML in quanto tale:

res/layout/custom_layout.xml

<merge> 
    <SomeView /> 
    <SomeOtherView /> 
    <!-- maybe more layout stuff here later --> 
    <LinearLayout 
     android:id="@+id/content" /> 
</merge> 

La ragione per usare <merge> è quello di semplificare la gerarchia. Tutte le visualizzazioni figlio verranno allegate alla classe personalizzata, che è un RelativeLayout. Se non si utilizza <merge>, si finisce con un RelativeLayout collegato a un altro RelativeLayout collegato a tutti i bambini, che può causare problemi.

HTH

+0

non è la soluzione, perché ho detto che voglio definire i figli altrove (non nella visualizzazione personalizzata). Più esattamente: ho i file di layout a.xml, b.xml, c.xml: tutti utilizzano la stessa vista personalizzata, ma con diversi bambini nel LinearLayout. – mreichelt

+0

Anche questo è perfettamente accettabile, e direi che il metodo più semplice sarebbe quello di sovrascrivere 'addView()' come descritto. Ho modificato l'esempio sopra. – Devunwired

+0

Grazie! È bello vedere questi problemi risolti anche dopo tanto tempo! :) – mreichelt

-3

è possibile utilizzare includono tag

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> 
    <include android:id="@+id/nav_bar_layout" layout="@layout/nav_bar" android:layout_above="@+id/web_view" /> 
    <WebView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/web_view" android:layout_centerInParent="true" /> 
    <include android:id="@+id/admob_layout" layout="@layout/admob_layout" android:layout_below="@+id/web_view" /> 
</RelativeLayout> 
+1

Ho già scritto che non voglio definire (o includere) le viste ogni volta che uso la mia vista personalizzata, perché alla fine loro _belong_ alla vista personalizzata. – mreichelt