Я хочу ссылаться на не конечную переменную внутри внутреннего класса, определенного другим способом

Я пишу приложение для Android, в котором у меня есть несколько кнопок, размещенных в сетке. Я хочу установить метод onClick для каждой кнопки, поэтому я написал следующее:

for (int i = 0; i < button.length; i++) { for (int j = 0; j < button[0].length; j++) { button[i][j].setOnClickListener(new View.OnClickListener() { public void onClick(View v) { press(i, j); } }); } } 

Где press(int i, int j) реализована в другом месте. Я получаю сообщение об ошибке: «Нельзя ссылаться на не конечную переменную i внутри внутреннего класса, определенного другим методом».

Итак, прямо сейчас у меня есть каждая функция, написанная так:

 button[0][0].setOnClickListener(new View.OnClickListener() { public void onClick(View v) { press(0, 0); } }); button[0][1].setOnClickListener(new View.OnClickListener() { public void onClick(View v) { press(0, 1); } }); // more like this... 

Это работает, но кажется глупым. Есть ли способ лучше?

Да, попробуйте следующее:

 for (int i = 0; i < button.length; i++) { for (int j = 0; j < button[0].length; j++) { final int listenerI = i; final int listenerJ = j; button[i][j].setOnClickListener(new View.OnClickListener() { public void onClick(View v) { press(listenerI, listenerJ); } }); } } 

Вы можете определить вспомогательный метод, чтобы установить слушателя для кнопки:

 private static void setListenerForButton(Button button, final int i, final int j) { button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { press(i, j); } }); } 

И тогда вы можете использовать его так

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

Это частный случай более общего решения: определить дополнительные final int переменные final int для использования во внутреннем классе и инициализировать их значениями i и j . В этом случае дополнительные final int переменные final int являются аргументами вспомогательной функции.

 for (int i = 0; i < button.length; i++) { for (int j = 0; j < button[0].length; j++) { final int localI = i; final int localJ = j; button[localI][localJ].setOnClickListener(...); } } 

Вы можете пройти с одним слушателем:

 package tayek.so9551773; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.*; import android.util.Log; public class So9551773 extends Activity { void press(int i,int j) { Log.d("so",i+","+j+" was clicked"); System.out.println(i+","+j+" was clicked"); } void addButtons(TableLayout tableLayout) { for(int i=0;i<buttons.length;i++) { TableRow tableRow=new TableRow(this); tableLayout.addView(tableRow); for(int j=0;j<buttons[i].length;j++) { buttons[i][j]=new Button(this); tableRow.addView(buttons[i][j]); buttons[i][j].setText(i+" "+j); buttons[i][j].setId(i*buttons.length+j); buttons[i][j].setOnClickListener(onClickListener); } } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d("so","created"); TableLayout tableLayout=new TableLayout(this); addButtons(tableLayout); setContentView(tableLayout); } Button[][] buttons=new Button[3][3]; OnClickListener onClickListener=new OnClickListener(){ public void onClick(View v) { int id=v.getId(); press(id/buttons.length,id%buttons.length); } }; } 

Объявить i и j как глобальную переменную во внешнем классе

Вы можете легко сделать что-то подобное в Javascript … но не Java 🙂

Вот несколько хороших ссылок:

Intereting Posts
Проблемы с тестированием библиотеки расширения APK Структура каталога проектов тестирования Android при использовании Eclipse Android Maps v2 – анимационная камера для включения большинства маркеров Можно ли показывать цифровые тексты в TextView в Android? Android: Как остановить воспроизведение мультимедиа (mp3) при появлении конкретных миллисекунд? Вызов DeleteLocalRef в собственном интерфейсе Java DatabaseReference и FirebaseDatabase – не могут разрешить символ Внедрение «более быстрого» backToTop – ListView Получить широту и долготу с помощью zipcode Клиент удаленного управления для Android Android: Crash: двоичная строка XML-файла: ошибка раздувания класса (с использованием SurfaceView) Горизонтальный центр выравнивает два текстовых изображения в макете Что вызывает отмененные сетевые запросы в Android Chrome Недавно выпущена «Аутентификация с сервисами Google Play», проблемы с получением токена через GoogleAuthUtil.getToken Android OkHttp, обновленный токен обновления