1

我正在尝试编写一个 Android 益智游戏,在第一个 Activity 中选择关卡,在第二个 Activity 中选择实际谜题。第一个活动必须向第二个活动提供有关所选拼图编号的信息,以便第二个活动可以加载适当的信息。这一直很好,直到我尝试清理我的代码并将我的按钮放入数组中:

例如,

我以前有:

    puzzle0 =  (Button) findViewById(R.id.puzzle0);
    puzzle1 =  (Button) findViewById(R.id.puzzle1);
    puzzle2 =  (Button) findViewById(R.id.puzzle2);


    puzzle0.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            Intent intent = new Intent(view.getContext(), Puzzle.class);
            intent.putExtra("LevelNumber", "0");
            startActivityForResult(intent, 0);
        }
    });


    puzzle1.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            Intent intent = new Intent(view.getContext(), Puzzle.class);
            intent.putExtra("LevelNumber", "1");
            startActivityForResult(intent, 1);
        }
    });

    puzzle2.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            Intent intent = new Intent(view.getContext(), Puzzle.class);
            intent.putExtra("LevelNumber", "2");
            startActivityForResult(intent, 2);
        }
    });

上面的代码效果很好,让我在第二个拼图活动中获得了正确的信息并加载了适当的拼图。

随着我开发了更多的谜题,使用 for 循环并稍微自动化一下似乎很合适:

private void initializePuzzleButtons() {
    for(int i = 0; i < numberOfPuzzles; i++)
    {
        Log.i("Trial","A" + i);
        int puzzleButtonID = getResources().getIdentifier("puzzle" + i, "button", this.getPackageName());
        Log.i("Trial","B" + i);
        puzzleButtons[i] = (Button) findViewById(puzzleButtonID);
        Log.i("Trial","C" + i);
        final int j = i;
        Log.i("Trial","D" + i);
    }
    for(int i = 0; i < numberOfPuzzles; i++)
    {   
        final int j = i;
        puzzleButtons[i].setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                Intent intent = new Intent(view.getContext(), Puzzle.class);
                Log.i("Trial","E" + j);
                intent.putExtra("LevelNumber", j + "");
                Log.i("Trial","F" + j);
                startActivityForResult(intent, j);
            }
        });
    }

}

LogCat 中的 Log 命令显示 NullPointerException 在第二个 for 循环中被抛出。也就是说,LogCat 显示 A1、B1、C1...、A2、B2、C3、... 一直到 D6(注意:numberOfPuzzles = 7),然后抛出异常。

我使用 j 变量的理由是需要一个最终变量(不能只使用 i),因为如 Eclipse 所示:“不能在以不同方法定义的内部类中引用非最终变量 j”如果 j 是不是最终的。

我认为 j 变量导致了问题,但我用文字 0 替换了每个 j 并且仍然得到 NullPointerException

那是,

for(int i = 0; i < numberOfPuzzles; i++)
    {   
        final int j = i;
        puzzleButtons[i].setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                Intent intent = new Intent(view.getContext(), Puzzle.class);
                Log.i("Trial","E" + 0);
                intent.putExtra("LevelNumber", 0 + "");
                Log.i("Trial","F" + 0);
                startActivityForResult(intent, 0);
            }
        });
    }

}

仍然会导致 NullPointerException。我可能在这里遗漏了一些简单的东西,但我已经绞尽脑汁好几个小时了。我在类似的困境中查看了其他人,但我发现的所有回复都没有使用“New View.OnClickListener”作为 setOnClickListener 的参数(他们使用“this”),因为他们不需要向子活动发送额外内容并且可以允许实现 OnClickListener 的 Activity。这在我的情况下不起作用,因为 Activity 通常只能实现 OnClickListener,并且我需要一个特定的字符串与每个 Button 相关联(使用 putExtra 命令)。

任何帮助将非常感激!

4

3 回答 3

1

如果您有多个功能相似的按钮。我建议您在 Activity 中实现 OnClickListener,而不是为每个按钮创建匿名侦听器。

要区分单击了哪个按钮,有两种方法可以做到这一点。1. 初始化按钮时,可以使用View.setTag() 方法给按钮设置标签。

  1. 使用 resID。

在您的情况下,我建议您使用方法 1,因为您需要在单击按钮时将级别传递给意图。当你初始化按钮时,你可以简单地用级别值设置按钮标签。

那么你的代码应该是这样的:

public class YourActivity extends Activity implements OnClickListener  {

    private void initializePuzzleButtons() {
        ...
        puzzleButtons[i].setOnClickListener(this);
        puzzleButtons[i].setTag(i);
        ...
    }

    @Override
    public void onClick(View view) {
        int level = (int)view.getTag(); 
        ...
    }
}
于 2012-06-21T05:58:25.290 回答
1

代替

int puzzleButtonID = getResources().getIdentifier("puzzle" + i, "button", this.getPackageName());

经过

int puzzleButtonID = getResources().getIdentifier("puzzle" + i, "id", this.getPackageName());
于 2012-06-21T05:57:13.063 回答
0

我认为应该按照链接使用

int id = getResources().getIdentifier("name_of_resource", "id", getPackageName());

于 2012-06-21T05:57:46.307 回答