Из того, что я прочитал, вы можете назначить onClick
обработчик кнопке двумя способами.
Использование android:onClick
атрибута XML, в котором вы просто используете имя открытого метода с подписью void name(View v)
или использование setOnClickListener
метода, в котором вы передаете объект, реализующий OnClickListener
интерфейс. Последний часто требует анонимный класс, который лично мне не нравится (личный вкус) или определение внутреннего класса, который реализует OnClickListener
.
Используя атрибут XML, вам просто нужно определить метод вместо класса, поэтому мне было интересно, можно ли сделать то же самое с помощью кода, а не в макете XML.
onClick
атрибута в файле макета. Это сделано благодаря параметруView v
. Вы просто проверяетеif (v == findViewById(R.id.button1
)) и т.д ..v.getId() == R.id.button1
, так как вам не нужно находить фактический контроль и делать сравнение. И вы можете использоватьswitch
вместо многих ifs.Ответы:
Нет, это невозможно с помощью кода. Android просто реализует
OnClickListener
для вас, когда вы определяетеandroid:onClick="someMethod"
атрибут.Эти два фрагмента кода одинаковы, просто реализованы двумя различными способами.
Реализация кода
Выше приведена реализация кода
OnClickListener
. И это реализация XML.Реализация XML
В фоновом режиме Android делает только код Java, вызывая ваш метод по событию click.
Обратите внимание, что с указанным выше XML Android будет искать
onClick
методmyFancyMethod()
только в текущей активности. Это важно помнить, если вы используете фрагменты, так как, даже если вы добавляете вышеупомянутый XML с использованием фрагмента, Android не будет искатьonClick
метод в.java
файле фрагмента, использованного для добавления XML.Еще одна важная вещь, которую я заметил. Вы упомянули, что не предпочитаете анонимные методы . Ты хотел сказать, что тебе не нравятся анонимные занятия .
источник
myFancyMethod()
) в текущее действие. Это важно, если вы используете фрагменты, так как программный способ установки слушателей onclick, вероятно, будет иметь метод, обрабатывающий щелчки в onCreateView () фрагмента ..., где он не будет найден, если на него ссылаются из XML.Когда я увидел верхний ответ, я понял, что моя проблема не в том, чтобы поместить параметр (View v) в причудливый метод:
При попытке получить доступ к нему из XML, следует использовать
Надеюсь, что это помогает кому-то.
источник
android:onClick
для API уровня 4 и выше, поэтому, если вы ориентируетесь на <1.6, вы не сможете его использовать.источник
Проверьте, если вы забыли опубликовать метод!
источник
Указание
android:onClick
атрибута приводит к внутреннемуButton
вызову экземпляраsetOnClickListener
. Следовательно, нет абсолютно никакой разницы.Чтобы иметь четкое понимание, давайте посмотрим, как
onClick
атрибут XML обрабатывается платформой.Когда файл макета раздувается, создаются все экземпляры, указанные в нем. В этом конкретном случае
Button
экземпляр создается с помощьюpublic Button (Context context, AttributeSet attrs, int defStyle)
конструктора. Все атрибуты в теге XML считываются из пакета ресурсов и передаются какAttributeSet
конструктору.Button
Класс наследуется отView
класса, что приводитView
к вызову конструктора, который заботится о настройке обработчика обратного вызова click черезsetOnClickListener
.Атрибут onClick , определенный в attrs.xml , называется в View.java как
R.styleable.View_onClick
.Вот код,
View.java
который выполняет большую часть работы за вас, звоняsetOnClickListener
сам по себе.Как видите,
setOnClickListener
вызывается для регистрации обратного вызова, как мы делаем в нашем коде. Разница лишь в том, что он используетсяJava Reflection
для вызова метода обратного вызова, определенного в нашей Деятельности.Вот причина проблем, упомянутых в других ответах:
Java Class getMethod
он используется, ищутся только функции со спецификатором открытого доступа. В противном случае будьте готовы обработатьIllegalAccessException
исключение.getContext().getClass().getMethod()
вызов ограничивает поиск метода текущим контекстом, которым является Activity в случае Fragment. Следовательно, метод ищется в классе Activity, а не в классе Fragment.Java Class getMethod
ищет метод, который принимает вView.class
качестве параметра.источник
Здесь очень хорошие ответы, но я хочу добавить одну строку:
В
android:onclick
XML, Android использует Java-отражение за сценой, чтобы справиться с этим.И, как объясняется здесь, отражение всегда замедляет работу. (особенно на Далвик В.М.). Регистрация
onClickListener
это лучший способ.источник
Обратите внимание, что если вы хотите использовать функцию onClick XML, соответствующий метод должен иметь один параметр, тип которого должен соответствовать объекту XML.
Например, кнопка будет связана с вашим методом через строку имени:
android:onClick="MyFancyMethod"
но объявление метода должно показывать:...MyFancyMethod(View v) {...
Если вы пытаетесь добавить эту функцию в пункт меню , он будет иметь такой же синтаксис в файле XML, но ваш метод будет объявлен как:
...MyFancyMethod(MenuItem mi) {...
источник
Другой способ настроить прослушиватели при нажатии - использовать XML. Просто добавьте атрибут android: onClick в свой тег.
Рекомендуется использовать атрибут xml «onClick» над анонимным Java-классом, когда это возможно.
Прежде всего, давайте посмотрим на разницу в коде:
Атрибут XML / атрибут onClick
Часть XML
Java часть
Анонимный Java-класс / setOnClickListener
XML часть
Java часть
Вот преимущества использования атрибута XML перед анонимным классом Java:
Конечно, не всегда возможно использовать атрибут Xml, вот причины, по которым мы бы его не выбрали:
источник
С Java 8 вы, вероятно, могли бы использовать Method Reference для достижения того, что вы хотите.
Предположим, это ваш
onClick
обработчик события для кнопки.Затем вы передаете
onMyButtonClicked
ссылку на метод экземпляра в такомsetOnClickListener()
вызове.Это позволит вам избежать явного определения анонимного класса самостоятельно. Однако я должен подчеркнуть, что Справочник по методам Java 8 на самом деле является просто синтаксическим сахаром. На самом деле он создает для вас экземпляр анонимного класса (так же как и лямбда-выражения), следовательно, с той же осторожностью, что и обработчик событий в стиле лямбда-выражения, применялся, когда вы приходите к отмене регистрации вашего обработчика событий. Эта статья объясняет это действительно приятно.
PS. Для тех, кому интересно, как я могу действительно использовать функцию языка Java 8 в Android, это любезно предоставлено библиотекой retrolambda .
источник
Да, Вы можете сделать свой
fragment
илиactivity
реализоватьView.OnClickListener
и когда вы инициализируете ваши новые объекты представления в коде, вы можете просто сделать
mView.setOnClickListener(this);
и это автоматически устанавливает все объекты представления в коде для использования
onClick(View v)
метода, который есть у васfragment
или чего- либоactivity
еще.чтобы определить, какое представление вызвало
onClick
метод, вы можете использовать оператор switch для этогоv.getId()
метода.Этот ответ отличается от ответа «Нет, это невозможно с помощью кода»
источник
источник
Поддерживая ответ Руиво, да, вы должны объявить метод как «общедоступный», чтобы иметь возможность использовать его в XML-клике Android - я разрабатываю приложение с таргетингом от API Level 8 (minSdk ...) до 16 (targetSdk ...).
Я объявил свой метод как закрытый, и он вызвал ошибку, просто объявив, что публичная работа великолепна.
источник
Будьте осторожны, хотя
android:onClick
XML кажется удобным способом обработки кликов,setOnClickListener
реализация делает нечто большее, чем добавлениеonClickListener
. В самом деле, это делает свойство viewclickable
истинным.Хотя это не может быть проблемой в большинстве реализаций Android, согласно конструктору телефона, кнопка всегда по умолчанию имеет clickable = true, но другие конструкторы в некоторых моделях телефонов могут иметь clickable = false по умолчанию для представлений не Button.
Так что установки XML недостаточно, вам нужно все время думать, чтобы добавить
android:clickable="true"
не кнопку, и если у вас есть устройство, на котором по умолчанию кликабельно = true, и вы забудете хотя бы один раз поместить этот атрибут XML, вы не заметите проблема во время выполнения, но получит обратную связь на рынке, когда она будет в руках ваших клиентов!Кроме того, мы никогда не можем быть уверены в том, как proguard будет запутывать и переименовывать атрибуты XML и метод класса, поэтому не на 100% безопасно, что у них никогда не будет ошибки в один прекрасный день.
Поэтому, если вы никогда не хотите иметь проблемы и никогда не думаете об этом, лучше использовать
setOnClickListener
библиотеки или библиотеки типа ButterKnife с аннотацией@OnClick(R.id.button)
источник
onClick
Атрибут XML также устанавливает ,clickable = true
потому что он вызываетsetOnClickListener
наView
внутреннеПредположим, вы хотите добавить событие клика как это
main.xml
В файле Java вы должны написать метод, подобный этому.
источник
Я пишу этот код в XML-файл ...
И напишите этот код во фрагменте ...
источник
Лучший способ сделать это с помощью следующего кода:
источник
Чтобы упростить вашу жизнь и избежать использования анонимного класса в setOnClicklistener (), реализуйте интерфейс View.OnClicklistener, как показано ниже:
Открытый класс YourClass расширяет CommonActivity реализует View.OnClickListener, ...
это позволяет избежать:
и идет прямо к:
источник