Damien Diehl
Damien Diehl

Reputation: 382

Specifying TableRow child dimensions programmatically

I'm trying to create a TableLayout programmatically, in order to make a grid-like layout with a configurable row and column count. This would likely be trivial to do in a layout file, but because each child element will be nearly identical and I want the row and column count to be configurable, I would like to do it programmatically if possible.

So far this is what I have.

MainActivity.java

private void displayBoard() {
    TableLayout l = (TableLayout) findViewById(R.id.GameGrid);
    l.setLayoutParams(new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));

    for (int y = 0; y < b.height(); y++) {
        TableRow r = new TableRow(this);
        r.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.WRAP_CONTENT, 15));
        for (int x = 0; x < b.width(); x++) {
            r.addView(b.getSpaceAt(x, y));
        }
        l.addView(r);
    }
}

Board.java

for (int y = 0; y < spaces.length; y++) {
    for (int x = 0; x < spaces[0].length; x++) {
        spaces[y][x] = new BoardSpace(context, x, y);
    }
}

BoardSpace.java

public class BoardSpace extends Button {
    private ReversiPiece piece;
    protected int x, y;

    private BoardSpace(Context c) {
        super(c);
    }

    public BoardSpace(Context c, int x, int y) {
        super(c);
    //  this.setWidth(25); // Doesn't make a difference, either
    //  this.setHeight(15); // Doesn't make a difference, either
        piece = null;
        this.x = x;
        this.y = y;
    }

    public ReversiPiece piece() {
        return piece;
    }

    public void setPiece(ReversiPiece p) {
        piece = p;
    }
}

I'm basically trying to create a grid of buttons, but so far I cannot get the size of the buttons to change so I can make sure they all fit on the screen. At the moment they appear at a standard size, and any changes I make to the LayoutParams definitions do not make a difference.

I suspect this issue has to do with my usage of LayoutParams. There are a lot of LayoutParams classes associated with each View type, so perhaps I'm not using the right one? Any help would be appreciated.

EDIT: Now creating a new TableLayout.LayoutParams object for each TableRow based on cyanide's recommendation, but the buttons are still displaying at default size.

Upvotes: 0

Views: 1164

Answers (2)

Damien Diehl
Damien Diehl

Reputation: 382

Got it! I was trying to manipulate the LayoutParams of my TableLayout and TableRows when in reality I needed to set TableRow.LayoutParams on the buttons themselves, when I add them to TableRow. This involves specifying the weight of each child element (Button) as well.

private void displayBoard() {
    TableLayout l = (TableLayout) findViewById(R.id.GameGrid);
    l.setLayoutParams(new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));

    for (int y = 0; y < b.height(); y++) {
        TableRow r = new TableRow(this);
        r.setWeightSum(b.width());
        for (int x = 0; x < b.width(); x++) {
            BoardSpace s = b.getSpaceAt(x, y);
            s.setLayoutParams(new TableRow.LayoutParams(
                    TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.MATCH_PARENT, 1.0f));
            r.addView(s);
        }
        l.addView(r);
    }
}

TableRow.setWeightSum() is used to set the weight sum of the row to the number of elements in the row, then passing a weight of 1 to the LayoutParams for the button causes the buttons to adjust in size to fit on the screen, as intended.

Surprisingly this answer was for a more generic question but this is what led me to the solution: How to set layout_weight attribute dynamically from code?

Upvotes: 0

cyanide
cyanide

Reputation: 3964

You are right, that's about LayoutParams, which must not be shared between views: each view should have its own copy of LayoutParams.

In other words, this is what you need:

r.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, 15));

About getSpaceAt (there is not code for it). Does it create a view programmatically? Remember to set LayoutParams and again it should be separate for each view.

Hopefully it will help.

Upvotes: 1

Related Questions