简体   繁体   中英

How to Position Buttons in an Array of Buttons (Android)

I made an array with buttons, and I want to place them in the form of a rectangle, like this:

[ ] [ ] [ ]

[ ] [ ] [ ] (xNum being 3 and yNum being 2)

    RelativeLayout gameLayout = (RelativeLayout) findViewById(R.id.gameLayout);
    x = xScreen/xNum - 20;
    y = yScreen/yNum - 20;

    RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams
(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);

    int id = getResources().getIdentifier("buttons_w2", "drawable", getPackageName());
    ImageView gameLogo = new ImageView(this);
    RelativeLayout.LayoutParams imagelp = new RelativeLayout.LayoutParams
(RelativeLayout.LayoutParams.WRAP_CONTENT, 70);
    gameLogo.setLayoutParams(imagelp);
    gameLogo.setImageResource(id);
    gameLayout.addView(gameLogo);

for (int i = 0; i < xNum; i++)
        {
            for (int j = 0; j < yNum; j++)
            {
                array[i][j] = new Button(this);
                array[i][j].setWidth(x);
                array[i][j].setHeight(y);
                array[i][j].setId(createId(i, j));

                if (i == 0) {
                }
                else {
                    lp.addRule(RelativeLayout.RIGHT_OF, array[i - 1][j].getId());
                }

                if (j == 0) {
                    lp.addRule(RelativeLayout.BELOW, gameLogo.getId());
                }
                else {
                    lp.addRule(RelativeLayout.BELOW, array[i][j - 1].getId());
                }

                array[i][j].setLayoutParams(lp);
                gameLayout.addView(array[i][j]);
            }
        }

Notes: gameLogo is an ImageView located at the top of the screen. Also, x and y are widths and heights that were generated by using the size of the screen minus a bit and then dividing by the number of buttons in the respective row/column.

Here is the createId method:

public int createId (int i, int j)
{
    if (String.valueOf(i).length() == 1 && String.valueOf(j).length() == 1)
    {
        return Integer.parseInt("0" + i + "0" + j);
    }
    else if (String.valueOf(i).length() == 1)
    {
        return Integer.parseInt("0" + i + j);
    }
    else if (String.valueOf(j).length() == 1)
    {
        return Integer.parseInt(i + "0" + j);
    }
    else
    {
        return Integer.parseInt(i + "" + j);
    }
}

I tried it with xNum being 1 and yNum being 2. Basically, I got the gameLogo, and then the Buttons layered above the gameLogo (so you could only see one button). Why does my code not work?

Your imageview does not have an id actually. Try to set it before creating the buttons.

In addition you should set AlignParentLeft fir the Buttons with i==0 to have them properly aligned leaving space for the other buttons to right of the first button in each row.

Update 1: (Since I don't have the computer around in the moment I cannot verify it works)

You are reusing one instance of layout parameters foreach view. Create one instance foreach Button within the for loop.

In addition pass the parameters in addView as the second parameter.

Furthermore you set the width and height explicitely although you set WRAP_CONTENT in the layout params. Set width and height during param creation.

Update 2
I now went over the entire code and identified some points.

  1. I made the buttons array a flat array calculating the index once.
  2. The create Id method was wrong. The idea you had is good, however in the case of i == j == 0 the Id evaluated to 0, which is an invalid ID equal to NO_ID breaking the layouting.

See this updated code, which actually works on my devices.

int x, y, xScreen, yScreen, xNum, yNum;
    Button[] array;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Display display = getWindowManager().getDefaultDisplay();
        Point   size    = new Point();
        display.getSize(size);
        xScreen = size.x;
        yScreen = size.y;
        xNum = 3;
        yNum = 2;

        RelativeLayout gameLayout = (RelativeLayout)     findViewById(R.id.gameLayout);
        x = xScreen / xNum;
        y = (int) (yScreen * 0.2);
        // y = yScreen / yNum - 20;

        RelativeLayout.LayoutParams lp       = null;
        int                         id       =     getResources().getIdentifier("buttons_w2", "drawable", getPackageName());
        ImageView                   gameLogo = new ImageView(this);
        RelativeLayout.LayoutParams imagelp  = new     RelativeLayout.LayoutParams(yScreen, 100);
        gameLogo.setImageResource(id);
        gameLogo.setId(123456);
        gameLayout.addView(gameLogo, imagelp);

        array = new Button[xNum * yNum];

        // Row (=j) first, then column. Reflected in createId
        for (int j = 0; j < yNum; ++j) {
            for (int i = 0; i < xNum; ++i) {
                lp = new RelativeLayout.LayoutParams(x, y);

                int index = (j * xNum) + i;
                int indexToLeft = (j * xNum) + (i - 1);
                int indexToTop = ((j - 1) * xNum) + i;
                int bid = createId(i, j);

                array[index] = new Button(this);
                array[index].setId(bid);

                if (j == 0) {
                    lp.addRule(RelativeLayout.BELOW, gameLogo.getId());
                } else {
                    lp.addRule(RelativeLayout.BELOW, array[indexToTop].getId());
                }

                if (i == 0) {
                    lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
                } else {
                    lp.addRule(RelativeLayout.RIGHT_OF, array[indexToLeft].getId());
                }

                gameLayout.addView(array[index], lp);
            }
        }
    }

    public int createId(int i, int j) {
        // Add 1 to each index value copied to this function, since the generated ID might
        // evaluate to 0, which is an invalid id!
        i += 1;
        j += 1;

        if (String.valueOf(i).length() == 1 && String.valueOf(j).length() == 1) {
            return Integer.parseInt(String.format("0%d0%d", j, i));
        } else if (String.valueOf(i).length() == 1) {
            return Integer.parseInt(String.format("0%d%d", j, i));
        } else if (String.valueOf(j).length() == 1) {
            return Integer.parseInt(String.format("%d0%d", j, i));
        } else {
            return Integer.parseInt(String.format("%d%d", j, i));
        } 
    }

Some remarks:

  • The createId could be optimized by always returning a three or two id reducing to one format and one call removing the if-else-blocks.
  • The indexToTop is only required to be calculated once per row-increment, ie:

indexToTop = (j - 1) * xNum;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM