设置OnClickListener并将putExtra添加到Intents时,带有数组按钮的空指针异常

时间:2012-06-21 05:41:19

标签: android arrays button nullpointerexception onclicklistener

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

例如,

我之前有过:

    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显示:“不能引用在另一个方法中定义的内部类中的非final变量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命令)。

任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:1)

替换

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

通过

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

答案 1 :(得分:1)

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

要区分单击哪个按钮,有两种方法可以执行此操作。 1.初始化按钮时,可以使用View.setTag()方法使用标记设置按钮。

  1. 使用resID。
  2. 在您的情况下,我建议您使用方法1,因为您需要在单击按钮时将级别传递给intent。初始化按钮时,只需使用级别值设置按钮标记即可。

    然后你的代码应该是这样的:

    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(); 
            ...
        }
    }
    

答案 2 :(得分:0)

我认为应该按照link

使用

int id = getResources()。getIdentifier(“name_of_resource”,“id”,getPackageName());