简体   繁体   English

如何在按钮数组中放置按钮(Android)

[英]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) [] [] [](xNum为3,yNum为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. 注意:gameLogo是位于屏幕顶部的ImageView。 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. 此外,x和y是通过使用屏幕尺寸减去一点然后除以相应行/列中的按钮数量而生成的宽度和高度。

Here is the createId method: 这是createId方法:

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). 我尝试将xNum设置为1,将yNum设置为2。基本上,我得到了gameLogo,然后在GameLogo上方放置了Buttons(因此您只能看到一个按钮)。 Why does my code not work? 为什么我的代码不起作用?

Your imageview does not have an id actually. 您的imageview实际上没有ID。 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. 另外,您应该将i == 0的Button设置为AlignParentLeft,以使其正确对齐,从而将其他按钮的空间留在每行中第一个按钮的右侧。

Update 1: (Since I don't have the computer around in the moment I cannot verify it works) 更新1 :(由于我暂时无法携带电脑,因此无法验证它是否可以正常工作)

You are reusing one instance of layout parameters foreach view. 您正在为每个视图重用布局参数的一个实例。 Create one instance foreach Button within the for loop. 在for循环中创建一个foreach Button实例。

In addition pass the parameters in addView as the second parameter. 另外,将addView中的参数作为第二个参数传递。

Furthermore you set the width and height explicitely although you set WRAP_CONTENT in the layout params. 此外,尽管在布局参数中设置了WRAP_CONTENT,但仍显式设置了宽度和高度。 Set width and height during param creation. 在参数创建期间设置宽度和高度。

Update 2 更新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. 创建ID方法错误。 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. 您的想法很好,但是在i == j == 0的情况下,Id评估为0,这是一个无效ID,等于NO_ID,破坏了布局。

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. 可以通过始终将三个或两个id简化为一种格式并调用一次除去if-else-blocks的方法来优化createId。
  • The indexToTop is only required to be calculated once per row-increment, ie: indexToTop只需要按行增量计算一次,即:

indexToTop = (j - 1) * xNum; indexToTop =(j-1)* xNum;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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