Внутри OnClickListener я не могу получить доступ ко многим вещам - как подойти?

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

findViewById(R.id.Button01).setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                Intent mainApps = new Intent(Intent.ACTION_MAIN);
                mainApps.addCategory(Intent.CATEGORY_LAUNCHER);
                List<ActivityInfo> activities = this.getPackageManager().queryIntentActivities(mainApps, 0);
                /*
                Intent intent = new Intent("com.sygic.drive/com.sygic/drive/.SygicDriveActivity");
                startActivity(intent);*/
            }

        });

в этом примере мне нужно получить PacketManager, и я не могу получить его, так как у меня нет контекста, доступного внутри OnClickListener.

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

Ответ 1

Замените this в вашем коде MyActivity.this, где MyActivity - это имя класса вашего подкласса Activity.

Объяснение: Вы создаете анонимный внутренний класс, когда используете эту часть своего кода:
new OnClickListener() {
Анонимные внутренние классы имеют ссылку на экземпляр класса, в котором они созданы. похоже, что вы создаете его внутри подкласса Activity, потому что findViewById - это метод Activity. Активность - это контекст, поэтому все, что вам нужно сделать, это использовать ссылку на него, которая у вас есть автоматически.

Ответ 2

Вы также можете реализовать интерфейс OnClickListener в своем классе и избежать необходимости анонимного внутреннего класса. Затем вы должны установить прослушиватель кликов следующим образом:

findViewById(R.id.Button01).setOnClickListener(this);

Если у вас несколько кнопок с помощью одного прослушивателя, вы можете использовать оператор switch с view.getId() (который соответствует идентификатору вида в R.id), чтобы различать их.

Ответ 3

Есть несколько вещей, которые вы можете сделать, вы можете создать внутренний класс, который реализует onClickListener и передать необходимые аргументы в конструктор класса. Я до сих пор не считаю, что это самый чистый подход. Обычно я просто создаю другой метод для выполнения своих действий. Поэтому в onClick (View v) я бы сделал что-то вроде этого.

onClick(View v){doMyAction(myParams)}

private void doMyAction(Object params){//do stuff}

И просто передайте необходимые параметры из метода слушателя методу вне слушателя.

Ответ 4

Измените конструктор Intent, который используется в Intent (context, classname), и используйте getApplicationContext() в вашем внутреннем классе. В любом случае, решила мою проблему.