Я пытаюсь написать игру-головоломку для 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);
}
});
}
}
Команды Log в LogCat показывают, что исключение NullPointerException выбрано во втором цикле. То есть, LogCat показывает A1, B1, C1..., A2, B2, C3,... вплоть до D6 (ПРИМЕЧАНИЕ: numberOfPuzzles = 7), а затем генерируется исключение.
Мое обоснование использования переменной j состоит в том, что требуется конечная переменная (нельзя использовать только i), поскольку, как показывает Eclipse: "Нельзя ссылаться на не конечную переменную j внутри внутреннего класса, определенного другим методом", если j не окончательный.
Я думал, что переменная j вызывает проблему, но я заменил каждый j буквой 0 и все еще получил исключение 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 (они используют "это"), поскольку им не нужно отправлять дополнительные данные в под-активность и может разрешать Действия для реализации OnClickListener. Это не сработало бы в моем случае, так как Activity могла только в целом реализовать OnClickListener, и мне нужна конкретная строка, которая должна быть связана с каждой кнопкой (с помощью команды putExtra).
Любая помощь приветствуется!
замещать
int puzzleButtonID = getResources().getIdentifier("puzzle" + i, "button", this.getPackageName());
От
int puzzleButtonID = getResources().getIdentifier("puzzle" + i, "id", this.getPackageName());
Если у вас несколько кнопок со схожими функциями. Я предлагаю вам внедрить OnClickListener в Activity, а не создавать анонимный прослушиватель для каждой кнопки.
Чтобы различить, какая кнопка нажата, есть два способа сделать это. 1. Когда вы инициализируете кнопки, вы можете установить кнопку с помощью тега, используя View.setTag()
.
В вашем случае я предлагаю вам использовать метод 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();
...
}
}
Я думаю, следует использовать по ссылке
int id = getResources(). getIdentifier ("name_of_resource", "id", getPackageName());