247 votes

GridLayout (pas GridView) comment étirer tous les enfants de manière uniforme

Je veux avoir une grille 2x2 avec un des boutons à l'intérieur. Ce n'est que ICS donc je suis en train d'utiliser la nouvelle GridLayout donné.

Voici le code XML de ma présentation:

 <?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/favorites_grid"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#00ff00"
    android:rowCount="2"
    android:columnCount="2">
  <Button
      android:text="Cell 0"
      android:layout_row="0"
      android:layout_column="0"
      android:textSize="14dip" />
  <Button
      android:text="Cell 1"
      android:layout_row="0"
      android:layout_column="1"
      android:textSize="14dip" />

  <Button
      android:text="Cell 2"
      android:layout_row="1"
      android:layout_column="0"
      android:textSize="14dip" />
  <Button
      android:text="Cell 3"
      android:layout_row="1"
      android:layout_column="1"
      android:textSize="14dip" />
</GridLayout>

Le problème est que mon point de vue ne pas étirer uniformément pour chaque ligne. Cela provoque beaucoup d'espace supplémentaire à la droite de mon GridLayout.

J'ai essayé de réglage layout_gravity="fill_horizontal" mais qui ne s'applique qu'à la dernière vue sur la ligne. Cela signifie que la Cellule 1 s'étend tout le chemin à donner suffisamment d'espace pour la Cellule de 0.

Réflexions sur la façon de remédier à cette situation?

85voto

HenrikS Points 1890

Il y a des limitations lors de l'utilisation de la GridLayout, la citation suivante est tirée de la documentation.

"GridLayout ne fournit pas de support pour le principe de poids, comme défini dans le poids. En général, il n'est donc pas possible de configurer un GridLayout pour distribuer l'excédent de l'espace non-trivial les proportions entre plusieurs lignes ou colonnes ... Pour un contrôle complet de plus l'excès de la distribution de l'espace dans une ligne ou une colonne; utiliser un LinearLayout sous-vue pour tenir les composants de la cellule groupe."

Voici un petit exemple qui utilise LinearLayout des sous-vues. (J'ai utilisé les Vues de l'Espace que prend inutilisé de la région et pousse les boutons dans la position désirée.)

<GridLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:columnCount="1"
>
    <TextView
        android:text="2x2 button grid"
        android:textSize="32dip"
        android:layout_gravity="center_horizontal" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" android:orientation="horizontal">
        <Space
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1" />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button 1" />
        <Space
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1" />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="start"
            android:text="Button 2" />
        <Space
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
    >
        <Space
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1" />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button 3" />
        <Space
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1" />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="start"
            android:text="Button 4" />
        <Space
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1" />
    </LinearLayout>
</GridLayout>

36voto

Rotemmiz Points 4152

Vous pouvez définir la largeur de chaque enfant de manière dynamique:

 GridLayout.LayoutParams params = (GridLayout.LayoutParams) child.getLayoutParams();
    params.width = (parent.getWidth()/parent.getColumnCount()) -params.rightMargin - params.leftMargin;
    child.setLayoutParams(params);
 

16voto

Aviral Points 471

Essayez d’ajouter ce qui suit à vos spécifications GridLayout. Cela devrait fonctionner.

android: useDefaultMargins = "true"

7voto

dberm22 Points 1370

J'ai enfin trouvé la solution. Comme Rotemmiz dit, vous devez le faire de façon dynamique par la suite. Ce code s'étend les boutons pour remplir la vue horizontalement, mais la même chose peut être fait pour la verticale.

public void fillview(android.support.v7.widget.GridLayout gl)
{
    Button buttontemp;

    //Stretch buttons
    int idealChildWidth = (int) ((gl.getWidth()-20*gl.getColumnCount())/gl.getColumnCount());
    for( int i=0; i< gl.getChildCount();i++)
    {
        buttontemp = (Button) gl.getChildAt(i);
        buttontemp.setWidth(idealChildWidth);
    }
}

(Le 20 est pour l'interne et à l'externe de rembourrage et les marges. Ce qui pourrait être fait de façon plus universelle, mais c'est beaucoup plus propre)

Ensuite, il peut être appelé comme ceci:

    android.support.v7.widget.GridLayout gl = (android.support.v7.widget.GridLayout)findViewById(R.id.buttongrid);
    ViewTreeObserver vto = gl.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {@Override public void onGlobalLayout() 
    {

            android.support.v7.widget.GridLayout gl = (android.support.v7.widget.GridLayout) findViewById(R.id.buttongrid);
            fillview(gl);

            ViewTreeObserver obs = gl.getViewTreeObserver();
            obs.removeGlobalOnLayoutListener(this);
    }});

Elle doit être faite par un observateur, parce que nous avons besoin d'attendre la vue à établir avant de nous appeler les points de vue.

1voto

Mitch Points 550

Je voulais avoir un centré sur table avec les étiquettes aligné à droite et les valeurs aligné à gauche. L'espace supplémentaire devrait être autour de la table. Après beaucoup d'expérimentation et de ne pas suivre ce que la documentation a dit que je devrais faire, je suis venu avec quelque chose qui fonctionne. Voici ce que j'ai fait:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="vertical" >

<GridLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:columnCount="2"
    android:orientation="horizontal"
    android:useDefaultMargins="true" >

    <TextView
        android:layout_gravity="right"
        android:text="Short label:" />

    <TextView
        android:id="@+id/start_time"
        android:layout_gravity="left"
        android:text="Long extended value" />

    <TextView
        android:layout_gravity="right"
        android:text="A very long extended label:" />

    <TextView
        android:id="@+id/elapsed_time"
        android:layout_gravity="left"
        android:text="Short value" />
</GridLayout>

Cela semble fonctionner, mais le GridLayout affiche le message:

"Ce GridLayout mise en page ou de ses LinearLayout parent est inutile"

Je ne sais pas pourquoi il est "inutile", quand il travaille pour moi.

Je ne suis pas sûr de savoir pourquoi cela fonctionne ou si c'est une bonne idée, mais si vous l'essayez, et peut fournir une meilleure idée, petite amélioration ou d'expliquer pourquoi cela fonctionne (ou ne fonctionne pas) je vous en serais reconnaissant les commentaires.

Merci.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X