Сам по себе обработчик - это контроллер кнопки и он должен быть в других обработчиках. Все вьюшки, которые представляют собой XML код - это слой представления и он просто показывает что-то пользователю. Контроллеры и представление должны быть порознь. И очень странно что гугл сделал возможность добавлять обработчик в XML. В любом случае, я не советую это использовать. К тому же гугл в своих приложениях НЕ добавляет этот код в XML. Да и вообще почти никто не добавляет.Только не поняла. Если так просто можно реализовать через xml файл, то зачем способ использования MainActivity как обработчика (и для меня вообще оказался не простой).
Урок 10. Оптимизируем реализацию обработчиков.
- Mikhail_dev
- Сообщения: 2386
- Зарегистрирован: 09 янв 2012, 14:45
- Откуда: Самара
Re: Урок 10. Оптимизируем реализацию обработчиков.
Re: Урок 10. Оптимизируем реализацию обработчиков.
Через xml может быть и просто, но...Алемарика писал(а):Ребята, подскажите, пожалуйста.
Сделала все по уроку 10. Только не поняла. Если так просто можно реализовать через xml файл, то зачем способ использования MainActivity как обработчика (и для меня вообще оказался не простой).
P.s. я пока разбираюсь только в самых азах, но хочется знать как правильно (и почему).
Спасибо.
0) Самое главное - Гугл не рекомендует (дродебы где-то куда-то была ссылка)
1) Подход через интерфейсы более подходит для Java (и так как любой Android разработчик отчасти Java разработчик это ему удобнее)
2) Когда что-то происходит неявно, это не очень хорошо. Например над проектом работает два человека. Пусть это вы, кто делает обработчики в XML и кто-то, кто так не делает. Пусть тот второй напишет обработчик как он привык. Вы смотрите его код: о кнопка, о обработчик кнопки, все понятно. Теперь вы сделали через xml. Второй смотрит ваш код. О функция "onClickStart()", нигде не используется, пожалуй ее можно удалить. И он удалит и после этого проект даже может быть собирется (хотя я не проверял), но приложение точно упадет при нажатии этой злополучной кнопки. Если же реализовать все явно через интерфейсы, то: а) удалите интерфейс, ide начнет ругаться на setOnClickListener и @Override у метода onClick; б) удалите метод onClick - будет ругаться на отсутствие метода; в) а setOnClickListener вы не удалите, потому что в этой строчке четко и ясно говорится что назначается слушатель для кнопки.
3) xml это внешний вид, программирование оставьте для Java
а вообще пятница, вечер я устал, не слушайте меня.
Re: Урок 10. Оптимизируем реализацию обработчиков.
Mikhail_dev писал(а): Сам по себе обработчик - это контроллер кнопки и он должен быть в других обработчиках. Все вьюшки, которые представляют собой XML код - это слой представления и он просто показывает что-то пользователю. Контроллеры и представление должны быть порознь. И очень странно что гугл сделал возможность добавлять обработчик в XML.
Спасибо. Признаюсь, что надеялась, что Вы меня убедите делать через xml (ибо ну уж очень просто). Но аргументация столь сильна, что я даже не мыслю так больше делатьklblk писал(а): Через xml может быть и просто, но...
0) Самое главное - Гугл не рекомендует (дродебы где-то куда-то была ссылка)
1) Подход через интерфейсы более подходит для Java (и так как любой Android разработчик отчасти Java разработчик это ему удобнее)
2) Когда что-то происходит неявно, это не очень хорошо. ...
Спасибо, что разложили в голове у меня все по полочкам.
Re: Урок 10. Оптимизируем реализацию обработчиков.
Ребята помогите пожалуйста. Только начал изучать Android, да и вообще программирование в целом. Пытаюсь сделать урок 10, вроде все правильно делаю (в Android Studio), но приложение в эмуляторе не запускается. Подскажите в чем может быть проблема?
MainActivity.java
[syntax=java]package ru.startandroid.p0102ActivityListener;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements View.OnClickListener {
TextView tvOut = (TextView) findViewById(R.id.tvOut);
Button btnOk = (Button) findViewById(R.id.btnOk);
Button btnCancel = (Button) findViewById(R.id.btnCancel);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btnOk:
// кнопка ОК
tvOut.setText("Нажата кнопка ОК");
break;
case R.id.btnCancel:
// кнопка Cancel
tvOut.setText("Нажата кнопка Cancel");
break;
}
}
}
[/syntax]
Лог ошибки
MainActivity.java
[syntax=java]package ru.startandroid.p0102ActivityListener;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements View.OnClickListener {
TextView tvOut = (TextView) findViewById(R.id.tvOut);
Button btnOk = (Button) findViewById(R.id.btnOk);
Button btnCancel = (Button) findViewById(R.id.btnCancel);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btnOk:
// кнопка ОК
tvOut.setText("Нажата кнопка ОК");
break;
case R.id.btnCancel:
// кнопка Cancel
tvOut.setText("Нажата кнопка Cancel");
break;
}
}
}
[/syntax]
Лог ошибки
Код: Выделить всё
03-18 10:35:52.914 2014-2014/ru.startandroid.p0102ActivityListener D/AndroidRuntime﹕ Shutting down VM
--------- beginning of crash
03-18 10:35:52.966 2014-2014/ru.startandroid.p0102ActivityListener E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: ru.startandroid.p0102ActivityListener, PID: 2014
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{ru.startandroid.p0102ActivityListener/ru.startandroid.p0102ActivityListener.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.Window.findViewById(int)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2209)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.Window.findViewById(int)' on a null object reference
at android.app.Activity.findViewById(Activity.java:2071)
at ru.startandroid.p0102ActivityListener.MainActivity.<init>(MainActivity.java:14)
at java.lang.reflect.Constructor.newInstance(Native Method)
at java.lang.Class.newInstance(Class.java:1572)
at android.app.Instrumentation.newActivity(Instrumentation.java:1065)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2199)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
03-18 10:36:09.663 2014-2014/ru.startandroid.p0102ActivityListener I/Process﹕ Sending signal. PID: 2014 SIG: 9
Re: Урок 10. Оптимизируем реализацию обработчиков.
findViewById() можно вызвать только после вызова setContentView().
И если вы действительно внимательно посмотрите урок, то увидите что там не так как у вас.
И если вы действительно внимательно посмотрите урок, то увидите что там не так как у вас.
Re: Урок 10. Оптимизируем реализацию обработчиков.
Поставил findViewById() после setContentView(). То же самое происходит. Да, у меня не так как в уроке, но это потому что урок делался для Eclipse, и много чего у меня в AS помечается как ошибка, методом проб и ошибок пришел к такому виду. Видимо где то что то неправильно, но он не подчеркивает, а просто в лог ошибку выводит(( Я вот не могу понять что именно у меня не так, и тяжело немножко сравнивать с кодом урока. Я пробовал просто код в конце урока вставить там почти все красненьким выделяет хотя все элементы я "обзываю" точь в точь как в уроках.klblk писал(а):findViewById() можно вызвать только после вызова setContentView().
И если вы действительно внимательно посмотрите урок, то увидите что там не так как у вас.
----------------------------
Странно, но решилась проблема тем что обозначил View элементы 2 раза.
[syntax=java]package ru.startandroid.p0102ActivityListener;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tvOut = (TextView) findViewById(R.id.tvOut);
Button btnOk = (Button) findViewById(R.id.btnOk);
Button btnCancel = (Button) findViewById(R.id.btnCancel);
btnOk.setOnClickListener(this);
btnCancel.setOnClickListener(this);
}
@Override
public void onClick(View v) {
TextView tvOut = (TextView) findViewById(R.id.tvOut);
Button btnOk = (Button) findViewById(R.id.btnOk);
Button btnCancel = (Button) findViewById(R.id.btnCancel);
switch (v.getId()) {
case R.id.btnOk:
// кнопка ОК
tvOut.setText("Нажата кнопка ОК");
break;
case R.id.btnCancel:
// кнопка Cancel
tvOut.setText("Нажата кнопка Cancel");
break;
}
}
}
[/syntax]
Если обозначить их только в "onCreate", то прога ругается на то что эти элементы неизвестны (я так понял) в "onClick".
Re: Урок 10. Оптимизируем реализацию обработчиков.
Думаю нужно вначале почитать книжку о Java, т.к. у вас проблема с элементарными вещами. Ну и неужели сложно посмотреть как это сделано в уроке?
Re: Урок 10. Оптимизируем реализацию обработчиков.
Неужели так сложно показать мне конкретно где ошибка? Неужели так сложно прочитать то, о чем я писал в предыдущем посте про урок, Eclipse и Android studio?klblk писал(а):Думаю нужно вначале почитать книжку о Java, т.к. у вас проблема с элементарными вещами. Ну и неужели сложно посмотреть как это сделано в уроке?
Re: Урок 10. Оптимизируем реализацию обработчиков.
А откуда я знаю где у вас ошибка, если я не знаю что за ошибка?Rozbyn писал(а):Неужели так сложно показать мне конкретно где ошибка? Неужели так сложно прочитать то, о чем я писал в предыдущем посте про урок, Eclipse и Android studio?klblk писал(а):Думаю нужно вначале почитать книжку о Java, т.к. у вас проблема с элементарными вещами. Ну и неужели сложно посмотреть как это сделано в уроке?
Написание кода в Eclipse и AS ничем не отличается!
Вот ваш код:
[syntax=java]public class MainActivity extends Activity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tvOut = (TextView) findViewById(R.id.tvOut);
Button btnOk = (Button) findViewById(R.id.btnOk);
Button btnCancel = (Button) findViewById(R.id.btnCancel);
btnOk.setOnClickListener(this);
btnCancel.setOnClickListener(this);
}
@Override
public void onClick(View v) {
TextView tvOut = (TextView) findViewById(R.id.tvOut);
Button btnOk = (Button) findViewById(R.id.btnOk);
Button btnCancel = (Button) findViewById(R.id.btnCancel);
switch (v.getId()) {
case R.id.btnOk:
// кнопка ОК
tvOut.setText("Нажата кнопка ОК");
break;
case R.id.btnCancel:
// кнопка Cancel
tvOut.setText("Нажата кнопка Cancel");
break;
}
}
}[/syntax]
Вот код из урока (полностью правильный и корректный):
[syntax=java]public class MainActivity extends Activity implements OnClickListener {
TextView tvOut;
Button btnOk;
Button btnCancel;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// найдем View-элементы
tvOut = (TextView) findViewById(R.id.tvOut);
btnOk = (Button) findViewById(R.id.btnOk);
btnCancel = (Button) findViewById(R.id.btnCancel);
// присваиваем обработчик кнопкам
btnOk.setOnClickListener(this);
btnCancel.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// по id определеяем кнопку, вызвавшую этот обработчик
switch (v.getId()) {
case R.id.btnOk:
// кнопка ОК
tvOut.setText("Нажата кнопка ОК");
break;
case R.id.btnCancel:
// кнопка Cancel
tvOut.setText("Нажата кнопка Cancel");
break;
}
}
}[/syntax]
Найдите отличия? Какие ошибки правильный вариант вызывает в AS?
И спрашивая "какие", я хочу получить конкретный текст ошибки, а не гадать что там у вас происходит. Вариантов может быть куча (неумения импортировать классы, косяки в xml, ошибки в градле и т.д.).
Re: Урок 10. Оптимизируем реализацию обработчиков.
Добрый день! У меня таже проблема, в AS неполучается реализовать этод метод т.к студия ругается примерно так:klblk писал(а):А откуда я знаю где у вас ошибка, если я не знаю что за ошибка?Rozbyn писал(а):Неужели так сложно показать мне конкретно где ошибка? Неужели так сложно прочитать то, о чем я писал в предыдущем посте про урок, Eclipse и Android studio?klblk писал(а):Думаю нужно вначале почитать книжку о Java, т.к. у вас проблема с элементарными вещами. Ну и неужели сложно посмотреть как это сделано в уроке?
Написание кода в Eclipse и AS ничем не отличается!
Вот ваш код:
[syntax=java]public class MainActivity extends Activity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tvOut = (TextView) findViewById(R.id.tvOut);
Button btnOk = (Button) findViewById(R.id.btnOk);
Button btnCancel = (Button) findViewById(R.id.btnCancel);
btnOk.setOnClickListener(this);
btnCancel.setOnClickListener(this);
}
@Override
public void onClick(View v) {
TextView tvOut = (TextView) findViewById(R.id.tvOut);
Button btnOk = (Button) findViewById(R.id.btnOk);
Button btnCancel = (Button) findViewById(R.id.btnCancel);
switch (v.getId()) {
case R.id.btnOk:
// кнопка ОК
tvOut.setText("Нажата кнопка ОК");
break;
case R.id.btnCancel:
// кнопка Cancel
tvOut.setText("Нажата кнопка Cancel");
break;
}
}
}[/syntax]
Вот код из урока (полностью правильный и корректный):
[syntax=java]public class MainActivity extends Activity implements OnClickListener {
TextView tvOut;
Button btnOk;
Button btnCancel;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// найдем View-элементы
tvOut = (TextView) findViewById(R.id.tvOut);
btnOk = (Button) findViewById(R.id.btnOk);
btnCancel = (Button) findViewById(R.id.btnCancel);
// присваиваем обработчик кнопкам
btnOk.setOnClickListener(this);
btnCancel.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// по id определеяем кнопку, вызвавшую этот обработчик
switch (v.getId()) {
case R.id.btnOk:
// кнопка ОК
tvOut.setText("Нажата кнопка ОК");
break;
case R.id.btnCancel:
// кнопка Cancel
tvOut.setText("Нажата кнопка Cancel");
break;
}
}
}[/syntax]
Найдите отличия? Какие ошибки правильный вариант вызывает в AS?
И спрашивая "какие", я хочу получить конкретный текст ошибки, а не гадать что там у вас происходит. Вариантов может быть куча (неумения импортировать классы, косяки в xml, ошибки в градле и т.д.).
- Вложения
-
- А при нажатии на Alt+Enter получается вот так
- Безымянный3.jpg (326.5 КБ) 14522 просмотра
-
- Безымянный2.jpg (313.24 КБ) 14522 просмотра
-
- Безымянный1.jpg (316.13 КБ) 14522 просмотра
Re: Урок 10. Оптимизируем реализацию обработчиков.
Sergiy_GT, замените строчку "import android.content.DialogInterface" на "import android.view.View.OnClickListener"
Re: Урок 10. Оптимизируем реализацию обработчиков.
Долго не мог понять в чем дело(извиняюсь, если дублирую кого-то) - привязал функцию третьим быстрым способом к кнопке.
Вот с таким кодом приложение вылетает при нажатии с исключением нулевого указателя. Если поиск по id перекинуть в саму функцию, то все нормально. В чем тут дело? Сам объект Кнопка принадлежит же классу mainActivity, и если инициализация происходит в одной её функции, то в другой должна нормально использоваться? Или мне пока стоит отложить андроид и идти учить азы явы?:)
Код: Выделить всё
public class MainActivity extends ActionBarActivity {
Button myBtn;
TextView myTxt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myBtn = (Button) findViewById(R.id.myBtn);
myTxt = (TextView) findViewById(R.id.myTxt);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
}
public void onClickStart(View v){
myTxt.setText("test");
}
Re: Урок 10. Оптимизируем реализацию обработчиков.
Да, спасибо, разобрался.Yennefer писал(а):Sergiy_GT, замените строчку "import android.content.DialogInterface" на "import android.view.View.OnClickListener"
Re: Урок 10. Оптимизируем реализацию обработчиков.
Здравствуйте. при изучении этого урока тоже возник вопрос в AndroidStudoi с OnClickListener.
Re: Урок 10. Оптимизируем реализацию обработчиков.
Посмотрел урок, появился вопрос:
можно ли после выполнения замены текста обработчиком сразу задать новый текст на кнопке?
Далее, при повторном клике на одну из двух кнопок текст снова менялся на новый и т.д.
Вроде как можно в цикл все загнать, но не представляю, каким образом....
можно ли после выполнения замены текста обработчиком сразу задать новый текст на кнопке?
Далее, при повторном клике на одну из двух кнопок текст снова менялся на новый и т.д.
Вроде как можно в цикл все загнать, но не представляю, каким образом....
Re: Урок 10. Оптимизируем реализацию обработчиков.
Здравствуйте! У меня Android Studio по умолчанию создает параметры как здесь public void onBtnClick(View v), но в уроках написано public void onBtnClick(View view). Есть ли какая-то разница? Как правильно?damager82 писал(а):Код: Выделить всё
public void onBtnClick(View v) { switch (v.getId()) { case R.id.button1: Log.d("qwe", "button1"); break; case R.id.button2: Log.d("qwe", "button2"); break; } }
Re: Урок 10. Оптимизируем реализацию обработчиков.
v и view это произвольные названия для передаваемых аргументов.driversti писал(а):Здравствуйте! У меня Android Studio по умолчанию создает параметры как здесь public void onBtnClick(View v), но в уроках написано public void onBtnClick(View view). Есть ли какая-то разница? Как правильно?damager82 писал(а):Код: Выделить всё
public void onBtnClick(View v) { switch (v.getId()) { case R.id.button1: Log.d("qwe", "button1"); break; case R.id.button2: Log.d("qwe", "button2"); break; } }
Семь раз отмерь - поставь студию.
Эклипс не студия, ошибка вылетит - не исправишь.
Скажи мне кто твой друг, и оба поставили студию.
Студия - свет, а эклипс - тьма.
Эклипс не студия, ошибка вылетит - не исправишь.
Скажи мне кто твой друг, и оба поставили студию.
Студия - свет, а эклипс - тьма.
Re: Урок 10. Оптимизируем реализацию обработчиков.
Посмотрел урок, почитал комментарии, но так и не могу понять как лучше обрабатывать события
таким образом, для каждой кнопки писать так:
или же использовать такой способ:
или же есть какой другой способ, так как все это кажется громоздким.
Подскажите пожалуйста как будет выглядеть наиболее правильный вариант.
таким образом, для каждой кнопки писать так:
Код: Выделить всё
(findViewById(R.id.btnCode)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
etCode.setText(interpretator.codedMessage(etDeCode.getText().toString(),
getResources().getStringArray(R.array.symbol), getResources().getStringArray(R.array.code)));
}
});
(findViewById(R.id.btnDeCode)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
etDeCode.setText(interpretator.encodeMessage(etCode.getText().toString(),
getResources().getStringArray(R.array.symbol), getResources().getStringArray(R.array.code)));
}
});
Код: Выделить всё
public void onClick(View v)
{
switch (v.getId())
{
case R.id.btnCreate:
{
LinearLayout.LayoutParams lParams=new LinearLayout.LayoutParams(wrapContent,wrapContent);
int btnGravity= Gravity.LEFT;
switch (rgGravity.getCheckedRadioButtonId())
{
case R.id.rbLeft:
{
.
.
.
}
Подскажите пожалуйста как будет выглядеть наиболее правильный вариант.
Re: Урок 10. Оптимизируем реализацию обработчиков.
[quote="YAndrei"или же есть какой другой способ, так как все это кажется громоздким.
Подскажите пожалуйста как будет выглядеть наиболее правильный вариант.[/quote]
Подскажите пожалуйста как будет выглядеть наиболее правильный вариант.[/quote]
Код: Выделить всё
свич(вью.ид){
case бтн1:
myMethod1();
break;
case бтн2:
myMethod2();
break;
}
Семь раз отмерь - поставь студию.
Эклипс не студия, ошибка вылетит - не исправишь.
Скажи мне кто твой друг, и оба поставили студию.
Студия - свет, а эклипс - тьма.
Эклипс не студия, ошибка вылетит - не исправишь.
Скажи мне кто твой друг, и оба поставили студию.
Студия - свет, а эклипс - тьма.
Re: Урок 10. Оптимизируем реализацию обработчиков.
YAndrei,
для кнопок можно легко и непринуждённо делать onClick автоматизированный, тем более АС умеет вставлять его прямо из файла разметки.
Ну а .setOnClickListener можно цеплять к любой view. Хоть к текстовому полю, хоть к кнопке, хоть к картинке.
Вам, как будущему разработчику, необходимо чётко понимать, и уметь применять, методику работы именно .setOnClickListener, потому что с onClick и так всё понятно
для кнопок можно легко и непринуждённо делать onClick автоматизированный, тем более АС умеет вставлять его прямо из файла разметки.
Ну а .setOnClickListener можно цеплять к любой view. Хоть к текстовому полю, хоть к кнопке, хоть к картинке.
Вам, как будущему разработчику, необходимо чётко понимать, и уметь применять, методику работы именно .setOnClickListener, потому что с onClick и так всё понятно