2012-10-18 13 views
9

Quello che voglio è avere un layout con 2 viste disposte verticalmente. Chiamiamo la vista superiore A e quella inferiore B. Voglio che la quantità di altezza data a B sia la sua altezza normale (cioè il contenuto di avvolgimento) eccetto che non voglio che sia dato più della metà dello spazio disponibile. A ottiene ciò che è rimasto.altezza wrap_content, ma limitata alla metà del genitore

Un altro modo per dire che A dovrebbe sempre ottenere almeno il 50% dell'altezza disponibile e B dovrebbe ottenere al massimo il 50%.

Non riesco a trovare un modo semplice per raggiungere questo obiettivo. Posso impostare entrambe le altezze di layout su 0 e dare loro pesi uguali che li rendono entrambi sempre al 50%, ma se B è inferiore al 50% dovrebbe essere dato solo ciò di cui ha bisogno.

L'unico modo che posso vedere è utilizzare una classe personalizzata per A o B e sovrascrivere su Misura per limitare l'altezza al 50% del genitore, ma sembra che ci dovrebbe essere un modo più semplice.

+0

Quindi, qual è l'input per definire quanto dovrebbe essere grande B? È possibile creare un layout dinamico nel codice ([LayoutParam di riferimento Android] (http://developer.android.com/reference/android/widget/LinearLayout.LayoutParams.html)). – MarchingHome

+0

L'input per determinare quanto dovrebbe essere grande B è il contenuto di B. B è un layout (attualmente un frammento) che contiene alcuni contenuti a dimensione fissa ma la maggior parte è un TextView il cui contenuto è dinamico. Potrebbe essere qualche riga di testo o una lunga pagina di testo. Se il testo in B è lungo e B è vincolato al 50%, il testo sarà scorrevole. –

+0

Hai cercato un modo per determinare quante righe di testo saranno in B e regolando dinamicamente l'altezza di B in base a quella? – MarchingHome

risposta

-1

Creare un layout lineare con due telai interni, ciascuno con il peso .5. All'interno di questi fotogrammi, posizionare le visualizzazioni, impostandole su wrap_content o match_parent come appropriato.

+0

Ma allora il contenuto di A non può superare il 50% o no? – MarchingHome

+1

@MarchingHome hai ragione. Non può superare il 50%. – Ahmad

+0

Non arriva abbastanza. Consente di espandere una piccola B al 50%. –

3

Ok, ho capito ora. Se ho capito bene che si desidera avere in questo modo:

if A > B -> do nothing 
if B > A & B > parent layout -> 50% to both of them 
if B > A & B < parent layout -> A = parent layout - B 

ho dovuto fare tutto in onWindowFocusChanged perché altrimenti nel onCreate l'altezza delle Visualizzazioni restituirebbe 0. L'ho fatto con 2 LinearLayouts come layout di bambino, ma puoi prendere ciò che vuoi.

mio XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:id="@+id/parent_lay" 
    android:orientation="vertical" 
    android:layout_height="match_parent" > 

//Layout A: 
    <LinearLayout 
     android:id="@+id/lay_1" 
     android:layout_width="match_parent" 
     android:background="@android:color/background_dark" 
     android:layout_height="10dp" > 
    </LinearLayout> 
//Layout B: 
    <LinearLayout 
     android:id="@+id/lay_2" 
     android:layout_width="match_parent" 
     android:layout_height="40dp" 
     android:background="#123456" > 

    </LinearLayout> 

</LinearLayout> 

MainActivity:

public class MainActivity extends Activity { 
    LinearLayout parent_lay; 
    LinearLayout lay_1; 
    LinearLayout lay_2; 
    int parent_height; 
    int lay_1_height; 
    int lay_2_heigth; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.activity_main, menu); 
     return true; 
    } 

    @Override 
    public void onWindowFocusChanged(boolean hasFocus) { 
     // TODO Auto-generated method stub 
     super.onWindowFocusChanged(hasFocus); 
     parent_lay = (LinearLayout) findViewById(R.id.parent_lay); 
     lay_1 = (LinearLayout) findViewById(R.id.lay_1); 
     lay_2 = (LinearLayout) findViewById(R.id.lay_2); 
     lay_1_height = lay_1.getHeight(); 
     lay_2_heigth = lay_2.getHeight(); 
     parent_height = parent_lay.getHeight(); 


     if (lay_2.getHeight() > lay_1.getHeight() 
       && lay_2.getHeight() > (parent_lay.getHeight()/2)) { 

      lay_1.setLayoutParams(new LinearLayout.LayoutParams(
        LayoutParams.MATCH_PARENT, 0, 1)); 

      lay_2.setLayoutParams(new LinearLayout.LayoutParams(
        LayoutParams.MATCH_PARENT, 0, 1)); 

     } else if (lay_2.getHeight() < (parent_lay.getHeight()/2)) { 
      lay_1.setLayoutParams(new LinearLayout.LayoutParams(
        LayoutParams.MATCH_PARENT, (parent_height - lay_2_heigth))); 

     } 

    } 

} 

Esempio: Se A è 60dp e B è 40dp:

enter image description here

.210

Se A è 60dp e B è 400dp:

enter image description here

+1

Grazie per tutto questo lavoro, ma non hai proprio capito bene le regole. B è sempre genitore - A. Se l'altezza misurata di A è inferiore alla metà del genitore usa quella, altrimenti usa la metà del genitore per la dimensione di A. –

+0

@dalewking Hai detto "B dovrebbe ottenere al massimo il 50%". - Quindi non più del 50%, questo è esattamente quello che ho fatto. Nel mio esempio B * è * sempre (genitore - A), a meno che non sia più del 50%, quindi l'approccio migliore sarebbe se l'altezza originale di B fosse maggiore del 50% che otterrebbe il maggior spazio possibile (50%) . – Ahmad

+0

Oops nella mia risposta Ho invertito A e B. A È sempre genitore - B. Se l'altezza misurata di B è inferiore alla metà del genitore usa quello, altrimenti usa la metà del genitore per la dimensione di B. Il cambiamento di messa a fuoco non è sicuramente il luogo per fare questo, ma ci sono gli ascoltatori del cambiamento di layout. Proverò con la mia soluzione che ho citato di seguito e se ciò non funziona rivisiterà la tua soluzione. –

0

È necessario scrivere il proprio componente per raggiungere questo obiettivo.

Ad esempio, se si utilizza LinearLayout qui, è possibile estendere un LinearLayout con il metodo overMid onMeasure. È possibile implementare su misura in questo modo:

@Override 
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

    final int width = getMeasuredWidth(); 
    final int height = getMeasuredHeight(); 
    setMeasuredDimension(width, height/2); 
} 

Questo codice non è abbastanza elegante. Se vuoi davvero farlo bene, copia il metodo onMeasure originale dal codice sorgente Android (http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/ android/widget/LinearLayout.java # LinearLayout.onMeasure% 28int% 2Cint% 29) e in measureVertical(int widthMeasureSpec, int heightMeasureSpec), impostare mTotalLength = mTotalLength/2.

Per informazioni dettagliate suMisura, visitare http://developer.android.com/guide/topics/ui/custom-components.html e http://developer.android.com/reference/android/view/View.html#onMeasure(int, int).

+0

Quello che hai lì farebbe sì che un oggetto occupasse metà dello spazio che normalmente impiegherebbe, il che non è quello che volevo. Voglio che prenda la metà del suo spazio genitore, ma solo se è più grande della metà del suo spazio genitore. Se è più piccolo, dovrebbe occupare solo la stanza di cui ha bisogno. –

Problemi correlati