2017-08-11 7 views
0

Je suis nouveau dans le développement d'Android, donc j'ai travaillé sur une application d'échecs afin de m'instruire. Cependant, je suis maintenant bloqué. Essentiellement, il me faut une bonne façon de dessiner une grille 8x8 de ImageButtons tel que:Comment remplir une grille avec ImageButtons par programme?

  1. Les boutons remplissent l'ensemble du réseau
  2. espace grille est uniformément répartie entre les boutons
  3. Il n'y a pas de lacunes entre les boutons (clarifier # 2)
  4. La grille est de forme carrée et sa taille peut être contrôlée (je voudrais être capable de redimensionner automatiquement en fonction de la taille de l'écran).

Ou, simplement, il devrait ressembler à un échiquier classique :)

J'ai essayé plusieurs mises en page sans succès. À l'heure actuelle, c'est le meilleur que je suis en mesure de le faire:

"Chessboard"

J'utilise un GridLayout de la manière suivante à l'intérieur de PlayGameActivity (Lorsque le conseil d'administration doit être établi):

public void onStart(){ 
    super.onStart(); 

    board = (GridLayout)findViewById(R.id.chessboard); 
    board.setColumnCount(8); 
    board.setRowCount(8); 

    for(int i = 0; i < 8; i++){ 
     for(int j = 0; j < 8; j++){ 
      ImageButton square = squares[i][j] = new ImageButton(this); 
      GridLayout.LayoutParams params = new GridLayout.LayoutParams(); 
      params.rightMargin = 0; 
      params.topMargin = 0; 
      params.height = params.WRAP_CONTENT; 
      params.width = params.WRAP_CONTENT; 
      params.setGravity(Gravity.FILL); 
      params.rowSpec = GridLayout.spec(i); 
      params.columnSpec = GridLayout.spec(j); 

      board.addView(square, params); 

      //board.addView(square); 
     } 
    }} 

Et est défini par chessboard XML comme ceci:

<GridLayout 
    android:id="@+id/chessboard" 
    android:layout_width="353dp" 
    android:layout_height="353dp" 
    android:layout_marginBottom="104dp" 
    android:layout_marginEnd="8dp" 
    android:layout_marginLeft="8dp" 
    android:layout_marginRight="8dp" 
    android:layout_marginStart="8dp" 
    android:layout_marginTop="104dp" 
    android:background="#000000" 
    android:gravity="center_horizontal" 
    app:layout_constraintBottom_toBottomOf="parent" 
    app:layout_constraintLeft_toLeftOf="parent" 
    app:layout_constraintRight_toRightOf="parent" 
    app:layout_constraintTop_toTopOf="parent" 
    tools:layout_constraintBottom_creator="1" 
    tools:layout_constraintLeft_creator="1" 
    tools:layout_constraintRight_creator="1" 
    tools:layout_constraintTop_creator="1"> 
</GridLayout> 

Toutes les solutions que j'ai trouvé pour ce type de problème ont été sous forme de XML Android. Peut-être que mes préoccupations à propos d'une telle approche sont basées sur l'ignorance, mais je crois comprendre que je devrais copier et coller 64 carrés dans un GridLayout ou quelque chose comme ça. En outre, je ne suis pas sûr de la façon dont je redimensionnerais en fonction de la taille de l'écran avec cette approche. Idéalement, je suis à la recherche d'une solution strictement programmatique (et c'est ma méthode préférée de conception de l'interface utilisateur de toute façon).

Répondre

0

Ma suggestion serait de modularisation avec xml en utilisant include (link):

<include layout="@layout/titlebar"/> 

L'utilisation include vous permet d'écrire un morceau de code XML une fois dans son propre fichier, puis utilisez plusieurs fois. Je suggère également de ne pas utiliser GridLayout dans la plupart des cas, car ils ne vous donnent pas autant de contrôle que certains autres types de mise en page. Si tel était mon code, ce que je ferais:

  1. Créer un ImageButton « carré » dans son propre fichier XML avec android:layout_weight="1".
  2. Créer une LinearLayout "ligne" dans son propre fichier XML avec android:orientation="horizontal", android:layout_weight="1" et android:weightSum="8", puis copier et coller 8 include s avec layout="@layout/[your_image_button]". Créez un LinearLayout extérieur où vous avez actuellement votre GridLayout Celui-ci aurait android:orientation="vertical" et android:weightSum="8". Ensuite, copiez et collez 8 include s avec layout="@layout/[your_linear_layout_row]".

Il y a plusieurs façons de faire cela, mais cela vous donne beaucoup de contrôle sur la façon dont tout est spatialement disposé, et sa logique est très similaire à l'approche 'array of arrays' que vous êtes. actuellement en train de tout mettre en place dynamiquement.Si vous voulez aller sur la route Java dynamique, ma suggestion serait de faire cette approche de grille LinearLayout en Java (vous pouvez même créer le ImageButton en XML et utiliser un LayoutInflater pour gonfler les copies de l'ImageButton). Dans la boucle externe for, vous pouvez créer un nouveau LinearLayout et l'ajouter au LinearLayout externe; puis dans la boucle interne for, créez ImageButton et ajoutez-le au LinearLayout interne.

Édition: Bon point sur les lignes étant différentes! Cela rend la solution XML pure moins propre. Si vous allez avec du XML pur, je ferais juste l'étape 2 ci-dessus deux fois: une fois avec le blanc puis le noir; l'autre fois avec du noir puis du blanc. Pour une tuile noire, cela pourrait ressembler à:

<include layout="@layout/your_imagebutton" 
    android:backgroundColor="#000" 
/> 

Si cette approche est trop lourd pour vous, vous pouvez définir les couleurs dynamiquement par une boucle à travers les lignes LinearLayout et tuiles ImageButton pour définir la couleur d'arrière-plan. Je pense que vous trouverez cela plus facile que dans votre approche GridLayout.

+0

Avec tous les maux de tête que j'ai vécus en essayant de faire fonctionner la solution programmatique, je pense que je vais juste me contenter de la solution XML. Dans ce cas, le nombre de cases dans le tableau ne changera pas, donc il n'y a pas beaucoup de justification pour poursuivre l'autre solution. Cependant, dans un échiquier, chaque case adjacente est de couleur opposée. Je vois comment je ferais une grille de boutons d'image avec votre méthode, mais y a-t-il un moyen de changer les couleurs sans le faire ensuite (c'est-à-dire accéder à chaque ligne et chaque carré de la ligne)? – TheRussianPatzer

+0

Je viens d'éditer ma réponse avec ma recommandation. Voir au dessus. – windedmoose

+0

J'ai finalement réussi à implémenter la version XML de la solution et ça marche très bien! Ce n'est pas la solution que je pensais que je voulais, mais elle s'est plutôt bien passée. Il s'avère que XML est une bonne façon de faire les choses si vous divisez les choses comme vous l'avez suggéré, alors merci! – TheRussianPatzer