Je voudrais utiliser un GridLayout
(pas GridView
) comme planche pour un jeu comme les échecs ou les dames. Comme je suis un peu réticent à utiliser un fichier XML avec 64 enfants View
, j'ai essayé de les ajouter par programmation.Comment définir layout_columnWeight pour un enfant GridLayout lorsqu'il est ajouté par programme?
Pour garder les choses simples, j'ai commencé à utiliser TextView
comme enfant View
pour le GridLayout
.
Mon problème est que les View
ne sont pas répartis uniformément, et que je ne sais pas comment obtenir une distribution régulière dans mon code java. Il n'y a pas de méthode comme "setWeight()" pour le réglage layout_columnWeight
et layout_rowWeight
.
À l'heure actuelle, ceci est mon activity_dynamic_grid_layout.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="80dp"
android:id="@+id/ivLogo"
android:background="#ff0000"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/>
<android.support.v7.widget.GridLayout
android:id="@+id/grid_layout"
android:background="#004080"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/ivLogo"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="36dp">
</android.support.v7.widget.GridLayout>
Je me suis fixé la largeur et la hauteur GridLayout
match_parent
ici, mais je les changer lors de l'exécution en utilisant un ViewTreeObserver.OnPreDrawListener
pour obtenir un tableau carré. Cela fonctionne, l'arrière-plan coloré montre un espace carré comme prévu.
Mon onCreate()
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dynamic_grid_layout);
GridLayout gl = (GridLayout) findViewById(R.id.grid_layout);
gl.setColumnCount(8);
gl.setRowCount(8);
for(int i=0; i<gl.getRowCount(); i++)
{
GridLayout.Spec rowSpec = GridLayout.spec(i, 1, GridLayout.FILL);
for(int j=0;j<gl.getColumnCount();j++)
{
GridLayout.Spec colSpec = GridLayout.spec(j,1, GridLayout.FILL);
TextView tvChild = new TextView(this);
tvChild.setText("[ " + i + " | " + j + " ]");
tvChild.setTextSize(18f);
tvChild.setTextColor(Color.WHITE);
tvChild.setGravity(Gravity.CENTER);
GridLayout.LayoutParams myGLP = new GridLayout.LayoutParams();
myGLP.rowSpec = rowSpec;
myGLP.columnSpec = colSpec;
gl.addView(tvChild, myGLP);
}
}
final View rootView = findViewById(R.id.dynamic_root);
rootView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener()
{
@Override
public boolean onPreDraw()
{
int w = rootView.getMeasuredWidth();
int h = rootView.getMeasuredHeight();
int min = Math.min(w, h);
ViewGroup.LayoutParams lp = gl.getLayoutParams();
lp.width = min - min % 9;
lp.height = lp.width;
gl.setLayoutParams(lp);
rootView.getViewTreeObserver().removeOnPreDrawListener(this);
return true;
}
});
}
Ce que j'ai déjà essayé:
je mets un TextView
enfant dans le fichier de mise en page et a essayé de copier le layout_columnWeight
et layout_rowWeight
de son GridLayout.LayoutParams
:
<android.support.v7.widget.GridLayout
...>
<TextView
android:id="@+id/clone_my_params"
android:text="[ 0 | 0 ]"
android:textColor="#ffffff"
android:textSize="18sp"
app:layout_column="0"
app:layout_row="0"
app:layout_columnWeight="1"
app:layout_rowWeight="1"
/>
</android.support.v7.widget.GridLayout>
Code additionnel dans onCreate()
, avant la double boucle:
TextView v = (TextView)gl.findViewById(R.id.clone_my_params);
v.setGravity(Gravity.CENTER);
GridLayout.LayoutParams gridLayoutParamsToCopy = new GridLayout.LayoutParams(v.getLayoutParams());
intérieur de la boucle, je sautée (i, j) = (0,0) et a changé
GridLayout.LayoutParams myGLP = new GridLayout.LayoutParams();
à
GridLayout.LayoutParams myGLP = new GridLayout.LayoutParams(gridLayoutParamsToCopy);
Avant le changement, tous les éléments étaient dans le coin supérieur gauche, l'espace excédentaire était donné à la dernière ligne/colonne. Après le changement, la première rangée/colonne avait l'espace excédentaire, aucun changement pour les autres éléments. L'appel gl.invalidate()
et/ou gl.requestLayout()
après que la double boucle n'a eu aucun effet.
Il semble donc que je n'ai pas réussi à définir le poids désiré en utilisant le constructeur de copie.
Tout d'abord, si tout ce que vous voulez est une grille de 8x8 carré, il pourrait être plus facile (et efficace) pour faire une coutume ViewGroup (il est la mise en œuvre serait assez simple). Deuxièmement, ne devriez-vous pas utiliser une méthode spec qui reçoit un flottant comme http://developer.android.com/reference/android/widget/GridLayout.html#spec(int, int, android.widget.GridLayout.Alignment, float) pour les Spec? – Luksprog
@Luksprog - sur le ViewGroup personnalisé: J'ai un prototype du jeu avec une vue personnalisée comme un plateau de jeu, remplaçant "onDraw()", et maintenant j'expérimente avec GridView ainsi que GridLayout. Je suis plutôt nouveau dans le développement Android et j'essaie de déterminer quelle version sera la meilleure du point de vue des performances. A propos de la méthode: OK, c'est ce qui se passe si le niveau de l'API est fixé à 14 - j'ai utilisé spec (int start, int size) et seulement maintenant remarqué une spécification (int start, float weight). Je pense que mon soutien GridLayout l'a aussi, peut-être que c'est ce qui me manquait. Merci pour l'indice! – 0X0nosugar
@Luksprog - mission accomplie :) L'ajout de "1f" comme dernier paramètre dans la spécification() a fait l'affaire. Voudriez-vous l'écrire comme une réponse pour que je puisse changer de sujet? – 0X0nosugar