Android onClick em XML vs. OnClickListener

86

Sei que uma pergunta com palavras semelhantes já foi feita antes, mas isso é diferente. Eu sou muito novo no desenvolvimento de aplicativos Android e tenho três perguntas sobre as diferenças entre o android:onclick=""atributo XML e o setOnClickListenermétodo.

  1. Quais sao as diferenças entre os dois? A diferença entre as duas implementações é encontrada em tempo de compilação ou tempo de execução ou ambos?

  2. Quais casos de uso são favoráveis ​​a qual implementação?

  3. Que diferença (s) o uso de fragmentos no Android faz na escolha da implementação?

KG6ZVP
fonte
1
Para o # 2: você deve ter cuidado ao usar o xml, onclickpois precisa garantir que todas as classes implementem esse método. Isso pressupõe que você esteja usando o layout mais de uma vez. No entanto, se você tivesse uma interface java para garantir que o método estivesse em todas as classes que o implementaram, não teria que se preocupar.
Uxonith
Ter uma interface java como você descreveu não seria praticamente o mesmo que estender ou implementar OnClickListener?
KG6ZVP
Já examinei isso antes e acho que há um pouco mais do que preferência, mas lamento não poder dizer muito mais, pois já faz um tempo. Gosto de android:onclickquando é conveniente, mas sei que às vezes causa problemas, e também não consigo me lembrar deles :)
Uxonith
xml onClick não funciona para elementos de layout aninhados que são dinamicamente aumentados na API de nível 19
Amit Kaushik
1
Raramente vi código de outras pessoas implementando android: onClick e é mais confuso quando você olha o código de outra pessoa. Como não tem todas as possibilidades de setOnClickListener, quase todo mundo usa apenas setOnClickListener na minha opinião
Cristão

Respostas:

122

Diferença entre OnClickListener e OnClick:

  • OnClickListener é a interface que você precisa implementar e pode ser configurada para uma visualização em código java.
  • OnClickListener é o que espera que alguém realmente clique, onclick determina o que acontece quando alguém clica.
  • Recentemente, o android adicionou um atributo xml às visualizações chamado android: onclick, que pode ser usado para lidar com cliques diretamente na atividade da visualização sem a necessidade de implementar nenhuma interface.
  • Você pode facilmente trocar uma implementação de ouvinte por outra, se necessário.
  • Um OnClickListener permite separar a ação / comportamento do evento de clique da Visualização que dispara o evento. Embora para casos simples isso não seja um grande negócio, para tratamento de eventos complexos, isso pode significar melhor legibilidade e manutenção do código
  • Como OnClickListener é uma interface, a classe que o implementa tem flexibilidade para determinar as variáveis ​​de instância e os métodos de que precisa para lidar com o evento. Novamente, isso não é um grande problema em casos simples, mas para casos complexos, não queremos necessariamente misturar as variáveis ​​/ métodos relacionados ao tratamento de eventos com o código da View que dispara o evento.
  • O onClick com associação de função no Layout XML é uma associação entre onClick e a função que ele chamará. A função deve ter um argumento (View) para que onClick funcione.

Ambos funcionam da mesma maneira, apenas que um é definido por meio do código java e o outro por meio do código xml.

Implementação do código setOnClickListener:

Button btn = (Button) findViewById(R.id.mybutton);

btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    myFancyMethod(v);
    }
});

// some more code

public void myFancyMethod(View v) {
    // does something very interesting
}

Implementação XML:

<?xml version="1.0" encoding="utf-8"?>
<!-- layout elements -->
<Button android:id="@+id/mybutton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Click me!"
    android:onClick="myFancyMethod" />
<!-- even more layout elements -->

Atuação:

Ambos têm o mesmo desempenho. O Xml é pré-analisado em código binário durante a compilação. portanto, não há sobrecarga no Xml.

Limitação:

android: onClick é para API de nível 4 em diante, portanto, se sua meta for <1.6, não poderá usá-lo.

Jebasuthan
fonte
`Xml é pré-analisado em código binário durante a compilação` O que esta declaração significa exatamente? Já que vi o dexcode de um apk que tem android: onClick em seu arquivo de manifesto, mas não encontrei nenhum código que
definisse
explicação incrível. +1
Zia Ur Rahman
1
Na verdade, há alguma sobrecarga em XML . Quando o botão é clicado pela primeira vez, a reflexão é usada para determinar o método que deve ser chamado . No entanto, isso é provavelmente insignificante para a maioria dos casos de uso (e a otimização prematura é a raiz de todos os males).
Yoel
21

Estou chocado ninguém falou sobre isso, mas tenha cuidado, embora android:onClickXML parece ser uma forma conveniente de alça clique, a setOnClickListeneraplicação fazer algo adicional de adicionar o onClickListener. Na verdade, isso tornava clickableverdadeira a propriedade view .

Embora possa não ser um problema na maioria das implementações do Android, de acordo com o construtor do telefone, o botão é sempre padrão para clickable = true, mas outros construtores em algum modelo de telefone podem ter um clickable = false padrão em visualizações que não são de botão.

Portanto, configurar o XML não é suficiente, você tem que pensar o tempo todo para adicionar um android:clickable="true"não botão, e se você tiver um dispositivo onde o padrão é clickable = true e você se esquecer de colocar esse atributo XML uma vez, você não notará o problema em tempo de execução, mas obterá o feedback do mercado quando estiver nas mãos de seus clientes!

Além disso, nunca podemos ter certeza de como o Proguard ofuscará e renomeará os atributos XML e o método de classe, portanto, não é 100% seguro que eles nunca terão um bug um dia.

Então, se você nunca quer ter problemas e nunca pensar sobre isso, é melhor usar setOnClickListenerbibliotecas como ButterKnife com anotações@OnClick(R.id.button)

Livio
fonte
1
Você teve alguma experiência (ou viu em algum lugar) que o bug ocorreu devido à ofuscação durante o uso android:onClick?
Akram
Obrigado, senhor! Sua resposta é muito útil!
Yi Shen
12

Simplesmente:

Se você tiver android:onClick = "someMethod" em xml , ele procura public void someMethodem sua classe Activity. OnClickListeneré chamado diretamente de sua atividade e está vinculado a algum particular View. Por exemplo someButton.setOnClickListenere no código abaixo é dito o que deve ser feito quando someButtoné pressionado.

Espero que ajude :)

marson
fonte
4

Como dito antes: ambos são uma forma de adicionar lógica em resposta a um evento, neste caso um evento de 'clique'.

Eu iria por uma separação entre lógica e apresentação, assim como fazemos no mundo HTML / JavaScript: deixe o XML para apresentação e adicione ouvintes de eventos por meio de código.

Stephan van Hoof
fonte
1
Concordo, a menos que seja um aplicativo muito pequeno com algum comportamento simples, todo o seu código de execução deve ser mantido separado e bem organizado, de preferência usando métodos separados
OzzyTheGiant 01 de
0

Se você tiver vários botões usando apenas um método, sugiro fazê-lo em java. Mas se você tiver um botão com um método específico, onClick em XML seria melhor.

Megs
fonte
0

É mais conveniente sempre usar o atributo android: onClick, a menos que você tenha um bom motivo para não fazê-lo, por exemplo, se você instanciar o Button em tempo de execução ou precisar declarar o comportamento do clique em uma subclasse Fragment.

Mustapha Hadid
fonte
3
Raramente vi código de outras pessoas implementando android: onClick e é mais confuso quando você olha o código de outra pessoa. Como não tem todas as possibilidades de setOnClickListener, quase todos usam apenas setOnClickListener na minha opinião
Cristão
0

Existem alguns motivos pelos quais você pode querer definir programaticamente um OnClickListener. A primeira é se você quiser alterar o comportamento do botão enquanto o aplicativo está em execução. Você pode apontar o botão para outro método ou apenas desabilitar o botão configurando um OnClickListenerque não faz nada.

Quando você define um ouvinte usando o onClickatributo, a visualização procura um método com esse nome apenas em sua atividade de host. Definir programaticamente um OnClickListenerpermite controlar o comportamento de um botão de algum lugar diferente de sua atividade de host. Isso se tornará muito relevante quando usarmos Fragments, que são basicamente mini atividades, permitindo que você crie coleções reutilizáveis ​​de visualizações com seu próprio ciclo de vida, que podem então ser montadas em atividades. Fragments sempre precisam ser usados OnClickListenerspara controlar seus botões, já que eles não são Activities, e não serão pesquisados ​​por ouvintes definidos em onClick.

Rohan Vachhani
fonte
-2

Acho que a principal diferença entre eles é:

OnClick: Quando você clica no botão com o dedo.

OnClickListner: pode ser uma escolha mais ampla que pode ser implementada em vários códigos.

Por exemplo, quando você digita url "ymail.com", o yahoo encontra seu nome de usuário e senha no navegador e habilita o botão de estado de clique para abrir seu e-mail. Esta ação deve ser implementada apenas em onClickListener.

Esta é minha ideia!

Seyyed Mahmood Ahmadi
fonte
Isso é interessante, mas há muito mais do que isso; o seu deveria ser um comentário.
Dakatine de