android/java:for循环阻止数组被调用

rsl1atfo  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(286)

我正在制作一个3x3网格类型的应用程序,我想通过添加for循环来调用按下的按钮来更改它。但是,我得到了异常“java.lang.arrayindexoutofboundsexception:length=3;索引=3“,因为for循环很奇怪。有人能帮我弄明白吗?我对java和编程都是新手。
代码:

public int j = 1;
public int i = 1;
public final int[][] buttons = new int[][] {
        {R.id.top_left_button, R.id.top_center_button, R.id.top_right_button},
        {R.id.left_button, R.id.center_button, R.id.right_button},
        {R.id.bottom_left_button, R.id.bottom_center_button, R.id.bottom_right_button}};
private Button lastButton;

public void setPlayer(Button button, int x, int y){
    button.setText("!");
    lastButton = (Button)findViewById(buttons[x][y]);
    lastButton.setText(" ");
    lastButton = button;
}
@Override

protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_game);

    ctx = this;

    final GameEngine game = new GameEngine();
    lastButton = (Button)findViewById(R.id.center_button);
    for (i = 0; i < buttons.length; i++) {
        for (j = 0; j < buttons[i].length; j++) {
            final Button button = (Button)findViewById(buttons[i][j]);
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Button b = (Button)v;
                    int x = i;
                    int y = j;
                    setPlayer(b, x , y);
                }
            });
        }
    }
myzjeezk

myzjeezk1#

你需要问的问题是:什么是价值观 i 以及 j 当按钮被点击时?
答案是 i 是: buttons.length. 因为这就是你留下的价值 i 在你离开环路的时候。
这应该起作用:

for (i = 0; i < buttons.length; i++) {
        final int iCopy = i;  
        for (j = 0; j < buttons[i].length; j++) {
            final Button button = (Button)findViewById(buttons[i][j]);
            final int jCopy = j;
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Button b = (Button)v;
                    int x = iCopy;
                    int y = jCopy;
                    setPlayer(b, x , y);
                }
            });
        }
    }

这将起作用的原因是,由于作用域的限制,您正在创建的新示例 iCopy 每次外部迭代,以及 jCopy 每次内部迭代。每个匿名者 OnClickListener 实现现在将使用适当的副本。

34gzjxbg

34gzjxbg2#

您应该像这样声明和初始化数组:

public final int[][] buttons = {
        {R.id.top_left_button, R.id.top_center_button, R.id.top_right_button},
        {R.id.left_button, R.id.center_button, R.id.right_button},
        {R.id.bottom_left_button, R.id.bottom_center_button, R.id.bottom_right_button}};

在循环中,您可以初始化新的i和j变量,如下所示:

for (int i = 0; i < buttons.length; i++) {
    for (int j = 0; j < buttons[i].length; j++) {
    ...
    ...
    }
}

无需在活动顶部声明。

相关问题