GridLayout e Row / Column Span Woe


121

Il post di presentazione del blog degli sviluppatori AndroidGridLayout mostra questo diagramma dell'impatto degli intervalli sull'allocazione automatica degli indici:

allocazione automatica degli indici

Sto tentando di implementarlo effettivamente utilizzando un file GridLayout. Ecco cosa ho finora:

<android.support.v7.widget.GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/com.commonsware.android.gridlayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    app:orientation="horizontal"
    app:columnCount="8">

    <Button
        app:layout_columnSpan="2"
        app:layout_rowSpan="2"
        android:layout_gravity="fill_horizontal"
        android:text="@string/string_1"/>

  <Button
    app:layout_columnSpan="2"
    android:layout_gravity="fill_horizontal"
    android:text="@string/string_2"/>

  <Button
    app:layout_rowSpan="4"
    android:text="@string/string_3"/>

  <Button
    app:layout_columnSpan="3"
    app:layout_rowSpan="2"
    android:layout_gravity="fill_horizontal"
    android:text="@string/string_4"/>

  <Button
    app:layout_columnSpan="3"
    android:layout_gravity="fill_horizontal"
    android:text="@string/string_5"/>

  <Button
    app:layout_columnSpan="2"
    android:layout_gravity="fill_horizontal"
    android:text="@string/string_6"/>

  <android.support.v7.widget.Space
    app:layout_column="0"
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

  <android.support.v7.widget.Space
    android:layout_width="36dp"
    />

</android.support.v7.widget.GridLayout>

Ho dovuto introdurre gli <Space>elementi per assicurarmi che ogni colonna avesse una larghezza minima, altrimenti avrei avuto un mucchio di colonne di larghezza zero.

Tuttavia, anche con loro, ottengo questo:

esempio GridLayout

In particolare:

  • Nonostante android:layout_gravity="fill_horizontal", i miei widget con estensioni di colonna non riempiono le colonne con estensione

  • Nonostante i android:layout_rowSpanvalori, nulla si estende su righe

Qualcuno può riprodurre il diagramma dal post del blog utilizzando un GridLayout?

Grazie!


178
Immagino che anche tu faccia domande :)
StackOverflowed

Risposte:


76

Sembra piuttosto hacky, ma sono riuscito a ottenere l'aspetto corretto aggiungendo una colonna e una riga extra oltre a ciò che è necessario. Quindi ho riempito la colonna extra con uno spazio in ogni riga che definisce un'altezza e ho riempito la riga extra con uno spazio in ogni colonna che definisce una larghezza. Per una maggiore flessibilità, immagino che queste dimensioni dello spazio possano essere impostate nel codice per fornire qualcosa di simile ai pesi. Ho provato ad aggiungere uno screenshot, ma non ho la reputazione necessaria.

<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnCount="9"
android:orientation="horizontal"
android:rowCount="8" >

<Button
    android:layout_columnSpan="2"
    android:layout_gravity="fill"
    android:layout_rowSpan="2"
    android:text="1" />

<Button
    android:layout_columnSpan="2"
    android:layout_gravity="fill_horizontal"
    android:text="2" />

<Button
    android:layout_gravity="fill_vertical"
    android:layout_rowSpan="4"
    android:text="3" />

<Button
    android:layout_columnSpan="3"
    android:layout_gravity="fill"
    android:layout_rowSpan="2"
    android:text="4" />

<Button
    android:layout_columnSpan="3"
    android:layout_gravity="fill_horizontal"
    android:text="5" />

<Button
    android:layout_columnSpan="2"
    android:layout_gravity="fill_horizontal"
    android:text="6" />

<Space
    android:layout_width="36dp"
    android:layout_column="0"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="1"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="2"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="3"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="4"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="5"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="6"
    android:layout_row="7" />

<Space
    android:layout_width="36dp"
    android:layout_column="7"
    android:layout_row="7" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="0" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="1" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="2" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="3" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="4" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="5" />

<Space
    android:layout_height="36dp"
    android:layout_column="8"
    android:layout_row="6" />

</GridLayout>

immagine dello schermo


7
Bene, IMHO è incrementalmente meno hacker rispetto all'altra soluzione presentata fino ad oggi - almeno qui, le dimensioni cablate sono negli Spaceelementi. Ho aggiunto uno screenshot per i futuri lettori. Grazie!
CommonsWare

Perché il rowCountset è 8? Abbiamo bisogno di 4 righe (la dimensione della più grande rowSpan) più quella extra per Spacecosì dovrebbe essere 5. Cosa mi manca?
curioustechizen

Sono appena andato con i conteggi di righe e colonne dall'immagine nella domanda originale (che è a sua volta da un post del blog di sviluppo Android). Ho quindi aggiunto 1 ai conteggi di righe e colonne per fare spazio agli spazi del bordo esterno. Dovrebbe funzionare bene anche con solo 5 righe.
kturney

5
Trovo che questa soluzione <Gridlayout>funzioni solo rispetto a<android.support.v7.widget.GridLayout>
Didia

Come posso impostare dinamicamente row_span e column span ... funzionerà?

17
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <GridLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:columnCount="8"
        android:rowCount="7" >

        <TextView
            android:layout_width="50dip"
            android:layout_height="50dip"
            android:layout_columnSpan="2"
            android:layout_rowSpan="2"
            android:background="#a30000"
            android:gravity="center"
            android:text="1"
            android:textColor="@android:color/white"
            android:textSize="20dip" />

        <TextView
            android:layout_width="50dip"
            android:layout_height="25dip"
            android:layout_columnSpan="2"
            android:layout_rowSpan="1"
            android:background="#0c00a3"
            android:gravity="center"
            android:text="2"
            android:textColor="@android:color/white"
            android:textSize="20dip" />

        <TextView
            android:layout_width="25dip"
            android:layout_height="100dip"
            android:layout_columnSpan="1"
            android:layout_rowSpan="4"
            android:background="#00a313"
            android:gravity="center"
            android:text="3"
            android:textColor="@android:color/white"
            android:textSize="20dip" />

        <TextView
            android:layout_width="75dip"
            android:layout_height="50dip"
            android:layout_columnSpan="3"
            android:layout_rowSpan="2"
            android:background="#a29100"
            android:gravity="center"
            android:text="4"
            android:textColor="@android:color/white"
            android:textSize="20dip" />

        <TextView
            android:layout_width="75dip"
            android:layout_height="25dip"
            android:layout_columnSpan="3"
            android:layout_rowSpan="1"
            android:background="#a500ab"
            android:gravity="center"
            android:text="5"
            android:textColor="@android:color/white"
            android:textSize="20dip" />

        <TextView
            android:layout_width="50dip"
            android:layout_height="25dip"
            android:layout_columnSpan="2"
            android:layout_rowSpan="1"
            android:background="#00a9ab"
            android:gravity="center"
            android:text="6"
            android:textColor="@android:color/white"
            android:textSize="20dip" />
    </GridLayout>

</RelativeLayout>

Immagine dello schermo


2
Grazie! La cosa interessante è che se passo al GridLayoutdal pacchetto di supporto Android, il layout si rompe, suggerendo che i due non sono completamente compatibili. Inoltre, spero davvero che ci sia un modo per farlo che non coinvolga le dimensioni di cablaggio dei widget. Lascerò questo passaggio per un po ', per vedere quali altre risposte arrivano (se ce ne sono), ma accetterò la tua se non si presenterà niente di meglio. Grazie ancora!
CommonsWare

4
"Se passo a GridLayout dal pacchetto di supporto Android, il layout si interrompe" - in realtà, è stata colpa mia, non ho convertito il richiesto android: attributi in app:quelli, utilizzando lo spazio dei nomi XML del backport. Funziona con il backport.
CommonsWare

Ho trovato un modo per avere alcune dimensioni dinamicamente, ma è solo se l'intera larghezza delle colonne o delle righe è già definita da viste adiacenti. Non credo che funzionino come i pesi e distribuiscano lo spazio equamente a seconda delle campate definite. Non è perfetto ma funziona perfettamente per ciò di cui ho bisogno nel mio progetto attuale.
HandlerExploit

Bene, il tuo esempio è più simile all'approccio di un AbsoluteLayout mescolato con uno per un RelativeLayout, non è vero? Questo non è né dinamico né portatile. Perché esattamente hai bisogno di un GridLayout per questo? Comunque, GridLayout è, imho, rotto o incompleto ...
Bondax

@Bondax Questa implementazione definisce chiaramente l'elemento della griglia in altezza, larghezza, larghezza della colonna e estensione della colonna. Il layout della griglia farà fluttuare gli elementi della griglia all'interno dello spazio limitato quando sono definite larghezze diverse per la griglia (larghezza dello schermo). Questo era un requisito per un progetto e questo ha risolto perfettamente il problema.
HandlerExploit

6

Devi impostare sia layout_gravity che layout_columntWeight sulle tue colonne

<android.support.v7.widget.GridLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView android:text="سوم شخص"
        app:layout_gravity="fill_horizontal"
        app:layout_columnWeight="1"
        />

    <TextView android:text="دوم شخص"
        app:layout_gravity="fill_horizontal"
        app:layout_columnWeight="1"
        />

    <TextView android:text="اول شخص"
        app:layout_gravity="fill_horizontal"
        app:layout_columnWeight="1"
        />
 </android.support.v7.widget.GridLayout>

2

La libreria GridLayout di supporto Android V7 semplifica la distribuzione dello spazio in eccesso grazie al principio del peso. Per allungare una colonna, assicurati che i componenti al suo interno definiscano un peso o una gravità. Per evitare che una colonna si allunghi, assicurarsi che uno dei componenti nella colonna non definisca un peso o una gravità. Ricorda di aggiungere la dipendenza per questa libreria. Aggiungi com.android.support:gridlayout-v7:25.0.1 in build.gradle.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:columnCount="2"
app:rowCount="2">

<TextView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:gravity="center"
    android:text="First"
    app:layout_columnWeight="1"
    app:layout_rowWeight="1" />

<TextView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:gravity="center"
    android:text="Second"
    app:layout_columnWeight="1"
    app:layout_rowWeight="1" />

<TextView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:gravity="center"
    android:text="Third"
    app:layout_columnWeight="1"
    app:layout_rowWeight="1" />

<TextView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:gravity="center"        
    app:layout_columnWeight="1"
    app:layout_rowWeight="1"
    android:text="fourth"/>

</android.support.v7.widget.GridLayout>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.