[Android Software Development] freekyfrogy:
I use a dynamically generated table of buttons in the app I'm working on. You can set the X and Y size and it will create a grid of ImageButtons. The way that I did it was instead of trying to fiddle with generating them in XML, I made the XML up to the TableLayout that contains the buttons and then from there went on to create them in the java code itself. the code for the MainGame.java file which declares all of this is as follows:

package com.freekyfrogy.treasure;

import java.util.Random;

import android.app.Activity;
import android.content.Context;
import android.graphics.PorterDuff.Mode;
import android.os.Bundle;
import android.text.Editable;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;

import com.freekyfrogy.treasure.R.drawable;

public class MainGame extends Activity implements OnClickListener {

static int X, Y = 5;
static int numChests = 8;
int scoreCount = 0;
final int NUM_SWAPS = 10000;

TableLayout mainTable;
TableRow[] row = new TableRow[Y];
ImageButton[][] button = new ImageButton[X][Y];
ImageView treasure;
TextView score;
int buttonType[][] = new int[X][Y];
int sand = R.drawable.sand;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

treasure = new ImageView(this);
treasure.setBackgroundResource(R.drawable.treasure);
treasure.setVisibility(8);

mainTable = (TableLayout) findViewById(R.id.mainTable);
score = (TextView) findViewById(R.id.scoreCount);

shuffle();
makeButtons(mainTable);
}

public void shuffle() {
int loops = 0;
for(int y=0; y<Y; y++){
for(int x=0; x<X; x++){
loops++;
if(loops<=numChests){
buttonType[x][y] = 1;
}
else{
buttonType[x][y] = 0;
}
}
}

Random generator = new Random();
for (int i=0; i<NUM_SWAPS; i++){
int x1 = generator.nextInt(X);
int y1 = generator.nextInt(Y);
int x2 = generator.nextInt(X);
int y2 = generator.nextInt(Y);

//swap
int temp = buttonType[x1][y1];
buttonType[x1][y1] = buttonType[x2][y2];
buttonType[x2][y2] = temp;
}
}

public void makeButtons(View v){
int id = 0;
for(int y=0; y<Y; y++){
row[y] = new TableRow(this);
row[y].setGravity(Gravity.CENTER);
mainTable.addView(row[y]);
for(int x=0; x<X; x++){
id++;
button[x][y] = new ImageButton(this);
button[x][y].setBackgroundResource(drawable.sand);
button[x][y].setOnClickListener(this);
button[x][y].setId(id);
button[x][y].setMinimumWidth(75);
button[x][y].setMinimumHeight(75);
button[x][y].setAdjustViewBounds(true);
button[x][y].setMaxHeight(80);
button[x][y].setMaxWidth(80);
if(buttonType[x][y]==1){
button[x][y].setImageResource(drawable.treasure);
button[x][y].setColorFilter(0x00000000, Mode.CLEAR);
button[x][y].setId(id+1000);
}
row[y].addView(button[x][y]);
}
}
}

public void toast(){
Toast.makeText(this, "TOASTING YOU!!!", Toast.LENGTH_SHORT).show();
}

public void onClick(View v) {
v.findViewById(v.getId()).setBackgroundResource(R.drawable.sanddug);
if(v.getId() >= 1000){
((ImageView) v.findViewById(v.getId())).setColorFilter(0x000000, Mode.SRC_ATOP);
v.findViewById(v.getId()).setId(v.getId() - 1000);
scoreCount = scoreCount+100;
}
score.setText(Integer.toString(scoreCount));

}
}
}