GridLayout et Row / Column Span Woe

121

L'article du blog des développeurs Android présentantGridLayout ce diagramme montre comment les intervalles affectent l'allocation d'index automatique:

allocation d'index automatique

J'essaye d'implémenter réellement cela en utilisant un GridLayout. Voici ce que j'ai jusqu'à présent:

<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>

J'ai dû introduire les <Space>éléments pour m'assurer que chaque colonne avait une largeur minimale, sinon, j'aurais un tas de colonnes de largeur nulle.

Cependant, même avec eux, je comprends ceci:

exemple GridLayout

Notamment:

  • Malgré tout android:layout_gravity="fill_horizontal", mes widgets avec des étendues de colonnes ne remplissent pas les colonnes étendues

  • Malgré les android:layout_rowSpanvaleurs, rien ne s'étend sur les lignes

Quelqu'un peut-il reproduire le diagramme du billet de blog en utilisant un GridLayout?

Merci!

CommonsWare
la source
178
Je suppose que même vous posez des questions :)
StackOverflowed

Réponses:

76

Cela semble assez hacky, mais j'ai réussi à obtenir le bon look en ajoutant une colonne et une ligne supplémentaires au-delà de ce qui est nécessaire. Ensuite, j'ai rempli la colonne supplémentaire avec un espace dans chaque ligne définissant une hauteur et j'ai rempli la ligne supplémentaire avec un espace dans chaque col définissant une largeur. Pour plus de flexibilité, j'imagine que ces tailles d'espace pourraient être définies dans le code pour fournir quelque chose de similaire aux poids. J'ai essayé d'ajouter une capture d'écran, mais je n'ai pas la réputation nécessaire.

<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>

capture d'écran

Kturney
la source
7
Eh bien, à mon humble avis, c'est progressivement moins piraté que l'autre solution présentée à ce jour - au moins ici, les tailles câblées sont dans les Spaceéléments. J'ai ajouté une capture d'écran pour les futurs lecteurs. Merci!
CommonsWare
Pourquoi l' rowCountensemble est-il à 8? Nous avons besoin de 4 lignes (la taille de la plus grande rowSpan) plus une supplémentaire pour Spacecela devrait être 5. Que me manque-t-il?
curioustechizen
Je viens de choisir le nombre de lignes et de colonnes de l'image de la question originale (qui provient elle-même d'un article de blog de développement Android). J'ai ensuite ajouté 1 au nombre de lignes et de colonnes pour faire de la place pour les espaces de bordure extérieure. Cela devrait également fonctionner correctement avec seulement 5 lignes.
kturney
5
Je trouve que cette solution ne fonctionne qu'avec <Gridlayout>par opposition à<android.support.v7.widget.GridLayout>
Didia
Comment puis-je définir dynamiquement row_span et column span ... cela fonctionnera?
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>

Capture d'écran

HandlerExploit
la source
2
Merci! Ce qui est intéressant, c'est que si je passe au GridLayoutpackage de support Android, la mise en page se rompt, ce qui suggère que les deux ne sont pas complètement compatibles. En outre, j'espère vraiment qu'il existe un moyen de le faire qui n'implique pas les tailles de câblage des widgets. Je vais laisser ça tourner un peu, pour voir quelles autres réponses viennent (le cas échéant), mais j'accepterai la vôtre si rien de mieux ne se présente. Merci encore!
CommonsWare
4
"si je passe au GridLayout depuis le package Android Support, la mise en page se brise" - en fait, c'était ma faute, ne pas convertir les android:attributs requis en attributs app:, en utilisant l'espace de noms XML du backport. Cela fonctionne avec le backport.
CommonsWare
J'ai trouvé un moyen d'avoir certains d'entre eux de taille dynamique, mais ce n'est que si la largeur totale des colonnes ou des lignes est déjà définie par des vues adjacentes. Je ne pense pas qu'ils fonctionnent comme les poids et répartissent également l'espace en fonction des portées définies. Ce n'est pas parfait mais cela fonctionne parfaitement pour ce dont j'ai besoin dans mon projet actuel.
HandlerExploit
Eh bien, votre exemple ressemble plus à une approche d'AbsoluteLayout mélangée à une approche pour un RelativeLayout, n'est-ce pas? Ce n'est ni dynamique ni portable. Pourquoi avez-vous exactement besoin d'un GridLayout pour cela? Quoi qu'il en soit, GridLayout est, à mon avis, cassé ou inachevé ...
Bondax
@Bondax Cette implémentation définit clairement l'élément de grille en hauteur, largeur, largeur de colonne et étendue de colonne. La disposition de la grille fera flotter vos éléments de grille dans l'espace confiné lorsque différentes largeurs sont définies pour la grille (largeur de l'écran). C'était une exigence pour un projet et cela a parfaitement résolu le problème.
HandlerExploit
6

Vous devez définir à la fois layout_gravity et layout_columntWeight sur vos colonnes

<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>
Hossein Shahdoost
la source
2

La bibliothèque Android Support V7 GridLayout facilite la distribution de l'espace excédentaire en tenant compte du principe du poids. Pour étirer une colonne, assurez-vous que les composants à l'intérieur définissent un poids ou une gravité. Pour empêcher une colonne de s'étirer, assurez-vous que l'un des composants de la colonne ne définit pas un poids ou une gravité. N'oubliez pas d'ajouter une dépendance pour cette bibliothèque. Ajoutez com.android.support:gridlayout-v7:25.0.1 dans 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>
Permita
la source