Ce TP s'inspire du livre "Hello, Android: Introducing Google's Mobile Development Platform (Broché)". On y crée l'activité GridActivity contrôlant la grille principale du jeux de sudoku gridview (xml) et son modèle JeuxModel. Avant tout, reprendre le projet sudoku précédent.
On mémorise la grille à l'aide d'un tableau grid d'entier de 9 * 9 et la case sélectionnée à l'aide d'une variable entière caseselec. Les valeurs par défaut de ces deux attribut sont définies comme des constantes def_grid et def_sel.
public class JeuxModel { private final int [] def_grid = {0,0,0,0,8,0,0,3,0,8,0,0,1, 9,0,5,0,0,1,7,0,0,0,0,8,6,0,0,0,0,4,0,0,3,0,0,0,9,0,0,0,0, 0,1,0,0,0,6,0,0,5,0,0,0,0,3,7,0,0,0,0,9,2,0,0,9,0,6,3,0,0, 7,0,1,0,0,7,0,0,0,0}; private final int def_sel = 15; private int[][] grid = null; private int caseselec = def_sel;
Développer les méthodes suivantes:
Le modèle de données doit être partagé entre de nombreuses classes, notamment :
De plus il ne doit y avoir qu'une seule occurrence de d'objet de type JeuxModele dans l'application. On utilise pour cela le patron Singleton qui garanti ceci simplement comme suit
public class JeuxModelSingleton { private static JeuxModel jm =null; private static int jeton = 0; public static JeuxModel recup(){ if (JeuxModelSingleton.jeton == 0){ jm = new JeuxModel(); jeton = 1; } return jm; }
};
La vue est définie dans le fichier xml gridvue.xml. Celle-ci peut être construite comme un tableau de trois lignes et trois colonnes où chaque grosse cellule est elle-même un tableau de trois lignes et trois colonnes. Les cellules les plus à l'intérieur sont des TextView. Pour représenter correctement le tableau on peut
<?xml version="1.0" encoding="utf-8"?> <TableLayout android:id="@+id/table" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:layout_width="fill_parent" android:background="@color/m_bleu" android:stretchColumns="*"> <TableRow > <TableLayout android:layout_margin="1dip" android:stretchColumns="*" android:layout_height="fill_parent"> <TableRow> <TextView android:paddingTop="@dimen/mt" android:paddingBottom="@dimen/mb" android:id="@+id/TextView0" android:background="@color/m_noir" android:typeface="monospace" android:layout_margin="1dip" android:gravity="center" /> <TextView android:paddingTop="@dimen/mt" android:paddingBottom="@dimen/mb" android:id="@+id/TextView1" android:background=""@color/mon_noir"" android:typeface="monospace" android:layout_margin="1dip" android:gravity="center" /> <TextView android:paddingTop="@dimen/mt" android:paddingBottom="@dimen/mb" android:id="@+id/TextView2" android:background="@color/m_noir" android:typeface="monospace" android:layout_margin="1dip" android:gravity="center" /> </TableRow> <TableRow> ... </TableRow> <!-- sec. ligne du premier tableau --> <TableRow> ... </TableRow> <!-- tr. ligne du premier tableau --> </TableLayout> <TableLayout ...> ... </TableLayout> <!--second tableau --> <TableLayout ...> ... </TableLayout> <!--troisi. tableau --> </TableRow > <TableRow> ... </TableRow> <!-- seconde ligne --> <TableRow> ... </TableRow> <!-- troisi. ligne -->
Dans le dossier res, créer les fichiers
La vue doit pouvoir se modifier elle-même lorsqu'on sélectionne une case ou bien lorsqu'on saisit un nouveau nombre dans une case. Pour respecter ceci, on crée le pendant en Java du TableLayout déclaré en XML. Cette classe est uniquement composée
public class GridView extends TableLayout { TextView tv[][]= null; public GridView(Context context) { super(context); LayoutInflater li = ((Activity)context).getLayoutInflater(); li.inflate(R.layout.gridvue, this); this.setWillNotDraw(false); this.tv = new TextView[9][9]; for (int i=0; i< 9 ; i++){ for (int j=0; j< 9 ; j++){ String tid = "TextView"+new Integer(i*9+j).toString(); int resID = getResources().getIdentifier(tid,"id",context.getPackageName()); tv[i][j] = (TextView) this.findViewById(resID); } } }
protected void onDraw(Canvas canvas) { for (int i=0; i< 9 ; i++){ for (int j=0; j< 9 ; j++){ this.tv[i][j].setText(JeuxModelSingleton.recup().valueAt(i,j)); int col = (i*9+j == JeuxModelSingleton.recup().getCaseselec()) ? getResources().getColor(R.color.mon_ocean): getResources().getColor(R.color.mon_noir); this.tv[i][j].setBackgroundColor(col); } } } }
Il ne reste plus qu'à construire l'activité demandant l'affichage de la grille : GridActivity. Comme toute activité, elle contient une méthode onCreate(...) et puisqu'elle gère la grille, elle est capable de récupérer les événements de type pression sur l'écran.
L'activité contient un attribut v qui est de type GridView. La méthode onCreate instancie v et définie sa vue comme étant v.
La méthode onTouchEvent(MotionEvent event) vise à récupérer les événements dont l'action est MotionEvent.ACTION_DOWN. Le cas échéant, elle effectue le traitement suivant :