Pelo que li, você pode atribuir um onClick
manipulador a um botão de duas maneiras.
Usando o android:onClick
atributo XML no qual você acabou de usar o nome de um método público com a assinatura void name(View v)
ou usando o setOnClickListener
método no qual passa um objeto que implementa a OnClickListener
interface. O último geralmente requer uma classe anônima da qual pessoalmente não gosto (gosto pessoal) ou definição de uma classe interna que implemente o OnClickListener
.
Usando o atributo XML, você só precisa definir um método em vez de uma classe, então eu queria saber se o mesmo pode ser feito via código e não no layout XML.
onClick
atributo no arquivo de layout. Isso é feito graças ao parâmetroView v
. Você simplesmente confereif (v == findViewById(R.id.button1
)) etc.v.getId() == R.id.button1
, já que você não precisa encontrar o controle real e fazer uma comparação. E você pode usar um emswitch
vez de muitos ifs.Respostas:
Não, isso não é possível via código. O Android implementa apenas
OnClickListener
para você quando você define oandroid:onClick="someMethod"
atributo.Esses dois trechos de código são iguais, apenas implementados de duas maneiras diferentes.
Implementação de código
Acima está uma implementação de código de um
OnClickListener
. E esta é a implementação XML.Implementação XML
Em segundo plano, o Android não faz nada além do código Java, chamando seu método em um evento de clique.
Observe que, com o XML acima, o Android procurará o
onClick
métodomyFancyMethod()
apenas na atividade atual. É importante lembrar se você estiver usando fragmentos, pois mesmo se você adicionar o XML acima usando um fragmento, o Android não procurará oonClick
método no.java
arquivo do fragmento usado para adicionar o XML.Outra coisa importante que notei. Você mencionou que não prefere métodos anônimos . Você queria dizer que não gosta de aulas anônimas .
fonte
myFancyMethod()
) na atividade atual. Isto é importante se você estiver usando fragmentos, uma vez que a forma de programação de configuração onclick ouvintes provavelmente terá o método de manipulação de cliques em onCreateView de um fragmento () ... onde seria não ser encontrada se referido a partir de XML.Quando vi a resposta principal, percebi que meu problema não era colocar o parâmetro (View v) no método sofisticado:
Ao tentar acessá-lo a partir do xml, deve-se usar
Espero que ajude alguém.
fonte
android:onClick
é para o nível 4 da API em diante; portanto, se você estiver segmentando <1.6, não poderá usá-lo.fonte
Verifique se você esqueceu de colocar o método público!
fonte
A especificação de
android:onClick
resultados de atributos naButton
instância que chamasetOnClickListener
internamente. Portanto, não há absolutamente nenhuma diferença.Para ter um entendimento claro, vamos ver como o
onClick
atributo XML é tratado pela estrutura.Quando um arquivo de layout é inflado, todas as Visualizações especificadas nele são instanciadas. Nesse caso específico, a
Button
instância é criada usando opublic Button (Context context, AttributeSet attrs, int defStyle)
construtor. Todos os atributos na tag XML são lidos no pacote de recursos e transmitidosAttributeSet
para o construtor.Button
A classe é herdada daView
classe que resulta naView
chamada do construtor, que cuida da configuração do manipulador de retorno de chamada por cliquesetOnClickListener
.O atributo onClick definido em attrs.xml , é referido em View.java como
R.styleable.View_onClick
.Aqui está o código
View.java
que faz a maior parte do trabalho para você chamandosetOnClickListener
por si só.Como você pode ver,
setOnClickListener
é chamado para registrar o retorno de chamada, como fazemos em nosso código. A única diferença que ele usaJava Reflection
para chamar o método de retorno de chamada definido em nossa Atividade.Aqui está o motivo dos problemas mencionados em outras respostas:
Java Class getMethod
é usado, apenas as funções com especificador de acesso público são pesquisadas. Caso contrário, esteja pronto para lidar com aIllegalAccessException
exceção.getContext().getClass().getMethod()
call restringe a pesquisa do método ao contexto atual, que é Activity no caso de Fragment. Portanto, o método é pesquisado na classe Activity e não na classe Fragment.Java Class getMethod
procura o método que aceitaView.class
como parâmetro.fonte
Há respostas muito boas aqui, mas quero adicionar uma linha:
No
android:onclick
XML, o Android usa a reflexão java nos bastidores para lidar com isso.E como explicado aqui, a reflexão sempre diminui o desempenho. (especialmente na Dalvik VM). O registro
onClickListener
é uma maneira melhor.fonte
Observe que, se você deseja usar o recurso onClick XML, o método correspondente deve ter um parâmetro, cujo tipo deve corresponder ao objeto XML.
Por exemplo, um botão será vinculado ao seu método por meio da sequência de nomes:
android:onClick="MyFancyMethod"
mas a declaração do método deve mostrar:...MyFancyMethod(View v) {...
Se você estiver tentando adicionar esse recurso a um item de menu , ele terá exatamente a mesma sintaxe no arquivo XML, mas seu método será declarado como:
...MyFancyMethod(MenuItem mi) {...
fonte
Outra maneira de definir seus ouvintes de clique seria usar XML. Basta adicionar o atributo android: onClick à sua tag.
É uma boa prática usar o atributo xml “onClick” em uma classe Java anônima sempre que possível.
Primeiro de tudo, vamos dar uma olhada na diferença de código:
Atributo XML / atributo onClick
Parte XML
Parte Java
Classe Java anônima / setOnClickListener
Parte XML
Parte Java
Aqui estão os benefícios de usar o atributo XML sobre uma classe Java anônima:
Obviamente, nem sempre é possível usar o atributo Xml, eis as razões pelas quais não o escolhemos:
fonte
Com o Java 8, você provavelmente poderia usar a Referência de método para conseguir o que deseja.
Suponha que este seja seu
onClick
manipulador de eventos para um botão.Em seguida, você passa a
onMyButtonClicked
referência do método da instância em umasetOnClickListener()
chamada como esta.Isso permitirá que você evite definir explicitamente uma classe anônima. No entanto, devo enfatizar que a Referência de método do Java 8 é na verdade apenas um açúcar sintático. Na verdade, ele cria uma instância da classe anônima para você (assim como a expressão lambda), portanto, cuidado semelhante ao do manipulador de eventos no estilo da expressão lambda foi aplicado quando você cancela o registro do manipulador de eventos. Este artigo explica muito bem.
PS. Para quem está curioso sobre como realmente usar o recurso da linguagem Java 8 no Android, é uma cortesia da retrolambda biblioteca .
fonte
Sim, você pode criar
fragment
ouactivity
implementarView.OnClickListener
e quando você inicializa seus novos objetos de exibição no código, você pode simplesmente fazer
mView.setOnClickListener(this);
e isso define automaticamente todos os objetos de exibição no código para usar o
onClick(View v)
método que seufragment
ouactivity
etc possui.para distinguir qual visualização chamou o
onClick
método, você pode usar uma instrução switch nov.getId()
métodoEsta resposta é diferente da que diz "Não, isso não é possível via código"
fonte
fonte
Apoiando a resposta do Ruivo, sim, você deve declarar o método como "público" para poder usar o onclick XML do Android - estou desenvolvendo um aplicativo direcionado do nível 8 da API (minSdk ...) a 16 (targetSdk ...).
Eu estava declarando meu método como privado e causou erro, apenas declarando-o como público funciona muito bem.
fonte
Tenha cuidado, embora o
android:onClick
XML pareça ser uma maneira conveniente de lidar com o clique, asetOnClickListener
implementação faz algo adicional do que adicionar oonClickListener
. De fato, colocou a propriedade viewclickable
em true.Embora possa não ser um problema na maioria das implementações do Android, de acordo com o construtor de telefone, o botão é sempre padrão como clickable = true, mas outros construtores em alguns modelos de telefone podem ter um clickable = false padrão nas visualizações que não são do botão.
Portanto, definir o XML não é suficiente, você deve pensar o tempo todo para adicionar
android:clickable="true"
um botão não, e se você tiver um dispositivo em que o padrão seja clicável = true e você esquecer uma única vez para colocar esse atributo XML, não perceberá o problema em tempo de execução, mas receberá o feedback do mercado quando ele estiver nas mãos de seus clientes!Além disso, nunca podemos ter certeza de como o programa irá ofuscar e renomear atributos XML e método de classe, portanto, não é 100% seguro que eles nunca terão um bug um dia.
Portanto, se você nunca quiser ter problemas e nunca pensar nisso, é melhor usar
setOnClickListener
ou bibliotecas como o ButterKnife com anotações@OnClick(R.id.button)
fonte
onClick
atributo XML também defineclickable = true
porque chamasetOnClickListener
naView
internamenteSuponha, você deseja adicionar um evento de clique como este
main.xml
No arquivo java, você deve escrever um método como este.
fonte
Estou Escreva este código no arquivo xml ...
E escreva esse código no fragmento ...
fonte
A melhor maneira de fazer isso é com o seguinte código:
fonte
Para facilitar sua vida e evitar a Classe Anônima em setOnClicklistener (), implemente uma Interface View.OnClicklistener como abaixo:
classe pública YourClass estende CommonActivity implementa View.OnClickListener, ...
isso evita:
e vai diretamente para:
fonte