2012-05-22 13 views
14

Ho un relativeLayout come di seguito:RelativeLayout Aggiungi regola "RelativeLayout.LEFT_OF" non funziona

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="horizontal" 
    android:id="@+id/parent" > 

    <ListView 
     android:layout_width="360dp" 
     android:layout_height="600dp" 
     android:id="@+id/list" 
     android:inputType="text" 
     android:maxLines="1" 
     android:layout_margin="50dp" 
     android:layout_alignParentRight="true" 
     /> 
</RelativeLayout> 

Nel codice Java, voglio aggiungere una vista a sinistra del ListView, ma non ha lavorato:

m_relativeLayout = (RelativeLayout)findViewById(R.id.parent); 
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); 
layoutParams.addRule(RelativeLayout.LEFT_OF, m_listView.getId()); 
Button button2 = new Button(this); 
button2.setText("I am button 2"); 
m_relativeLayout.addView(button2, layoutParams); 

solo se ho impostato il listview a alignParentRight, funzionerà. Si tratta di un bug Android o mi manca qualcosa?

Provo sempre addView(View child, int index, LayoutParams params), ma potrebbe funzionare solo nell'output lineare. Quindi c'è una soluzione normale per far funzionare il RelativeLayout.LEFT_OF?

EDIT

ho cercato RelativeLayout.BELOW e RelativeLayout.RIGHT_OF, e hanno funzionato perfettamente, quindi vuol dire che non ho abbastanza spazio per ottenere il pulsante? Ho provato a dare più spazio, ma non funziona ancora.

Uso Toshiba AT100 (1280 * 800) e orizzontale, quindi lo spazio è sufficiente. Prova below e right proprio come lo left. Penso che se metto un controllo A nel relativelayout, poi aggiungo il controllo B e decalcoli sulla sinistra del controllo A, il risultato dovrebbe essere il controllo B spingerà il controllo A alla sua destra, giusto?

+0

Dove viene visualizzata la vista? – Barak

+0

Il relativelayout è la vista principale dell'attività e ha lo spazio per aggiungere il pulsante. – dreamtale

+0

In realtà intendo, il pulsante non appare o appare in un luogo inappropriato? – Barak

risposta

22

Credo che se metto un controllo A in relativelayout, poi aggiungo il controllo B e dichiaro che è a sinistra del controllo A, il risultato dovrebbe essere il controllo B spingerà il controllo A alla sua destra, giusto?

L'assunzione è errata, il controllo A non verrà spostato a destra a meno che non sia stato specificato con una regola RelativeLayout.LayoutParams. RelativeLayout posiziona i propri figli uno sopra l'altro a partire dall'angolo in alto a sinistra dello schermo se non si specificano le regole di posizionamento per essi.Quando si aggiunge View A allo RelativeLayout senza alcuna regola (come layout_alignParentRight) verrà inserito a partire dall'angolo in alto a sinistra dello schermo. Quindi, quando aggiungi View B, la regola to_leftOf si applicherà a questa posizione View ma questa regola non significa nulla per lo View A che manterrà la sua posizione sullo schermo. Questo farà sì che View B sia posizionato a sinistra di View A ma al di fuori dello schermo come View I limiti iniziano dal bordo sinistro dello schermo.

Il Button saranno collocate alla sinistra del ListView quando si utilizza layout_alignParentRight="true" perché ora c'è spazio per vedere in realtà il Button (non è più al di fuori). funziona in un LinearLayout perché il LinearLayout dispone i propri figli in una riga o colonna (in base all'orientamento), pertanto quando si aggiunge uno View in una posizione specifica, verrà spostato l'altro Views a destra o in basso (a seconda dell'orientamento) (non esiste un posizionamento relativo delle viste in un LinearLayout, l'unica regola è che i bambini vengano uno dopo l'altro).

A partire dalla ListView senza regole impostate su di essa, ecco un esempio su come fare il Button ad apparire sulla sinistra del ListView:

RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); 
Button button2 = new Button(this); 
button2.setText("I am button 2"); 
button2.setId(1000); 
m_relativeLayout.addView(button2, layoutParams); 
RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams) m_listView 
      .getLayoutParams(); 
rlp.addRule(RelativeLayout.RIGHT_OF, button2.getId()); 

Il pulsante sarà aggiunto come normale al schermo e apparirà a partire dall'angolo in alto a sinistra dello schermo. Senza le due righe del codice sopra lo Button e lo ListView si sovrappongono poiché questo è il comportamento normale di RelativeLayout per i bambini senza alcuna regola su di essi. Modifichiamo quindi esplicitamente la posizione dello ListView per spostarlo a destra (con le ultime due righe del codice sopra).

+0

Uso Toshiba AT100 (1280 * 800) e orizzontale, quindi lo spazio è sufficiente Test 'below' e' right' proprio come 'left'. Penso che se metto un controllo A nel relativelayout, poi aggiungo il controllo B e decalcoli sulla sinistra del controllo A, il risultato dovrebbe essere il controllo B spingerà il controllo A alla sua destra, giusto? – dreamtale

+0

@dreamtale Ho frainteso la tua domanda la prima volta. Ho modificato la mia risposta, vedere se questo aiuta. – Luksprog

+0

Grazie per la tua risposta elaborata, l'ho fatto funzionare :) – dreamtale

1

Penso che potresti aver dimenticato di aggiungere m_listView a RelativeLayout o m_listView la visibilità sarebbe GONE.

Potete verificarlo?

+0

L'XML mostra il layout. – dreamtale

+0

Come posso vedere si stanno impostando i parametri di layout del layout relativo, ma si sta aggiungendo il pulsante nel layout lineare. Eiter usa LinearLayout.LayoutParams piuttosto che RelativeLayout.LayoutParams o chiama il metodo addView di istanza di RelativeLayout. – bhavindesai

+0

Vedere la mia domanda modificata. – dreamtale

2

Se i nomi delle variabili sono indicativi, è perché si aggiunge il widget a un LinearLayout, quindi i tag per un RelativeLayout vengono ignorati.

Questa linea è quello di cui sto parlando:

m_linearLayout.addView(button2, layoutParams); 

EDIT

Tu dici alignParentRight opere ... l'unica differenza è che ot non prende un parametro di ancoraggio . Forse m_listView.getId() non restituisce l'id corretto. Puoi eseguire il debugger e vedere se restituisce un valore appropriato.

Forse si potrebbe provare a chiamare l'id specificamente ...

layoutParams.addRule(RelativeLayout.LEFT_OF, R.id.list); 
+0

Vuoi dire che dovrei usare linearlayout? Puoi darmi maggiori dettagli? – dreamtale

+0

No, voglio dire che è necessario aggiungere una vista a un RelativeLayout affinché le regole RelativeLayout funzionino. Quel riferimento alla vista dice 'm_linearlayout', che mi dice che stai provando ad aggiungere la vista a LinearLayout invece che a RelativeLayout. Dato che non hai mostrato dove hai impostato il riferimento 'm_linearlayout', sto assumendo che tu stia usando un nome appropriato. A meno che tu non abbia 'm_linearlayout = (RelativeLayout) this.findViewById (R.id.parent)' da qualche parte, nel qual caso direi che hai scelto un nome di riferimento molto scarso per il tuo layout relativo. – Barak

+0

Ci scusiamo per questo, l'ho provato in un progetto precedente, e basta sostituire 'LinearLayout' a' RelativeLayout' e non cambiare il nome della variabile. Ho modificato la domanda. – dreamtale

1

setId prima che venga chiamato l'allineamento, in particolare per la nuova vista oggetto.

0

Se si utilizza un ID personalizzato e non un normale ID Android generato (ad esempio R.id.my_id), assicurarsi che l'ID non sia uguale a 0 (o negativo), altrimenti la regola verrà ignorata.

2

Per eseguirlo, utilizzare la vista predefinita ID o dichiararne uno. In valori cartella creare ids.xml quindi aggiungere un Articolo come questo:

<item name="imageViewID" type="id"/> 

utilizzare questo ID nel codice in cui si sta creando nuova istanza di vista in questo modo:

RelativeLayout layout=new RelativeLayout(context); 

ImageView imageView = new ImageView(context); 
imageView.setId(R.id.imageViewID); 

RelativeLayout.LayoutParams layoutParams = new LayoutParams(50, 50); 
layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL); 
layout.addView(imageView, layoutParams); 

TextView textView = new TextView(context); 

RelativeLayout.LayoutParams textViewParams= new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 
textViewParams.addRule(RelativeLayout.CENTER_HORIZONTAL); 
textViewParams.addRule(RelativeLayout.BELOW, imageView.getId()); 
layout.addView(nameView, nameLayoutParams); 

oppure possiamo usare direttamente questa funzione View.generateViewId() per eseguire lo stesso. In questo modo:

imageView.setId(View.generateViewId());