2010-03-16 13 views
6

Sto utilizzando una visualizzazione elenco in Android 1.5 per mostrare un elenco di immagini e testo accanto all'immagine. Sto provando a centrare verticalmente il testo, ma il testo è in cima alla riga anziché al centro. Qui di seguito è il mio layout:Come allineare verticalmente un elemento all'interno di un elenco utilizzando il layout relativo?

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/row" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:padding="10dip"> 

    <ImageView android:id="@+id/item_image" android:layout_width="wrap_content" 
     android:layout_height="wrap_content" android:paddingRight="10dip" 
     android:src="@drawable/default_image" android:layout_alignParentLeft="true" 
     android:layout_alignParentTop="true" 
     android:layout_alignParentBottom="true" 
     android:layout_centerVertical="true" 
     android:gravity="center_vertical"/> 

    <TextView android:id="@+id/item_title" 
     android:layout_width="wrap_content" android:layout_height="wrap_content" 
     android:layout_toRightOf="@id/item_image" 
     android:layout_alignParentTop="true" 
     android:layout_alignParentBottom="true" 
     android:layout_centerVertical="true" 
     android:gravity="center_vertical" 
     /> 

</RelativeLayout> 

Sembra strano che ho bisogno di impostare alignParentTop = "true" quando sto cercando di centrare il testo in verticale, ma se lo faccio non il testo non ha nemmeno vedere. Che cosa sto facendo di sbagliato?

risposta

16

EDIT in seguito alle osservazioni:

Si scopre fare questo lavoro con RelativeLayout non è facile. Nella parte inferiore della risposta ho incluso un RelativeLayout che dà l'effetto desiderato, ma solo fino a quando non è incluso in un ListView. Successivamente, si sono verificati gli stessi problemi descritti nella domanda. Questo è stato risolto utilizzando invece LinearLayout (s).

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:paddingLeft="10dp" 
    android:orientation="horizontal"> 

    <ImageView android:id="@+id/pickImageImage" 
     android:layout_width="100dp" 
     android:layout_height="80dp" 
     android:background="@drawable/icon" 
     android:scaleType="fitXY" 
     android:layout_marginRight="10dp"/> 

    <TextView android:id="@+id/pickImageText" 
     android:layout_height="fill_parent" 
     android:layout_width="fill_parent" 
     android:gravity="left|center_vertical" 
     android:text="I'm the text"/> 

</LinearLayout> 

Se si desidera avere due caselle di testo, è possibile nidificare un secondo orientation="vertical" e LinearLayout dopo l'ImageView e poi mettere le caselle di testo in là.

Questo funziona, ma devo ammettere che non so perché RelativeLayouts no. Ad esempio, questo blog post by Romain Guy indica specificamente che RelativeLayout dovrebbe. Quando ho provato, non ho mai avuto abbastanza lavoro; devo ammettere che non l'ho fatto esattamente come come ha fatto, ma le mie uniche modifiche erano con alcuni attributi di TextView, che non avrebbero dovuto fare la differenza.


Ecco la risposta originale:

Credo che tu stia confondendo Android con tutte quelle istruzioni un po 'contraddittorie in RelativeLayout. Ho riformattato la tua cosa a questo:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/row" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:padding="10dip"> 

    <ImageView android:id="@+id/item_image" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:paddingRight="10dip" 
     android:src="@drawable/icon" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentTop="true"/> 

    <TextView android:id="@+id/item_title" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_toRightOf="@id/item_image" 
     android:layout_centerVertical="true" 
     android:text="Blah!"/> 

</RelativeLayout> 

E che funziona bene. Ho rimosso molti dei tuoi ridondanti android:layout_alignParentxxx perché non erano necessari. Questa vista ora viene visualizzata con l'immagine nell'angolo in alto a sinistra e il testo verticalmente centrato accanto ad esso. Se vuoi che l'immagine sia centrata verticalmente, allora non puoi avere RelativeLayout su Android: layout_height = "wrap_content" perché sta cercando di non essere più alto dell'altezza dell'immagine. Dovresti specificare un'altezza, ad es. 80dp, quindi imposta ImageView su un'altezza fissa come 60dp con android: scaleType = "fitXY" per ridurlo per adattarlo correttamente.

+0

Grazie per aver provato. Voglio che il layout non sia più alto dell'immagine, quindi l'immagine va bene.Ho provato il tuo xml e ho visto la stessa cosa che vedevo con la mia. Il testo non viene visualizzato a meno che non aggiungo android: layout_alignParentTop = "true" a TextView, e quindi ovviamente è in alto giustificato invece che centrato. Hai messo il tuo all'interno di un ListView? –

+0

Hmm. Ha funzionato bene quando era una vista a sé stante, ma quando l'ho aggiunto a un ListView allora sì, ha smesso di funzionare. Ho appena provato alcune cose e nulla ha funzionato nel modo in cui avrebbe dovuto utilizzare RelativeLayout. Tuttavia, puoi ottenere lo stesso effetto usando un LinearLayout. Imposta l'orientamento su orizzontale e quindi imposta l'altezza di TextView su fill_parent, con gravità center_vertical. Se si desidera avere più TextView accanto all'icona, è possibile inserirle in un secondo LinearLayout verticale. Non è elegante, ma non riesco a capire perché i RelativeLayout non funzionassero ... –

+0

Potresti modificare la tua risposta per menzionare LinearLayout? Sembra funzionare. –

0

La direttiva di base lo farebbe, ma ImageView semplicemente non supporta l'allineamento della linea di base a partire da oggi. È possibile aggirare questo creando una sottoclasse di ImageView, sovrascrivere il metodo getBaseline() e restituire l'altezza dell'immagine.

+0

Grazie, proverò stasera per vedere se funziona. Sembra un problema dover sottoclasse ImageView ma ci provo. –

1

era bloccato su un problema simile per un po ', ma ho trovato questo da CommonsWare:

"Quando si gonfia il layout, utilizzare inflate(R.layout.whatever, parent, false), in cui padre è il ListView."

Funziona ma solo quando si imposta l'altezza della riga su un valore specifico (ovvero non è possibile utilizzare wrap_content).