Antes do favo de mel (Android 3), cada atividade foi registrada para manipular cliques de botão por meio da onClick
tag no XML de um layout:
android:onClick="myClickMethod"
Dentro desse método, você pode usar view.getId()
e uma instrução switch para fazer a lógica do botão.
Com a introdução do Honeycomb, estou dividindo essas atividades em fragmentos que podem ser reutilizados em muitas atividades diferentes. A maior parte do comportamento dos botões é independente da atividade, e eu gostaria que o código residisse no arquivo Fragments sem usar o método antigo (anterior à 1.6) de registrar o OnClickListener
botão para cada botão.
final Button button = (Button) findViewById(R.id.button_id);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
}
});
O problema é que, quando meu layout é inflado, ainda é a Atividade de hospedagem que está recebendo o botão, não os Fragmentos individuais. Existe uma boa abordagem para
- Registre o fragmento para receber os cliques do botão?
- Passar os eventos de clique da Atividade para o fragmento ao qual eles pertencem?
fonte
setOnClickListener
e,findViewById
para cada botão,onClick
foi por isso que foi adicionado, para simplificar as coisas.Respostas:
Você poderia fazer isso:
Atividade:
Fragmento:
Em resposta a @Ameen, que queria menos acoplamento, os fragmentos são reutilizáveis
Interface:
Atividade:
Fragmento:
fonte
Prefiro usar a seguinte solução para manipular eventos onClick. Isso funciona para Atividade e Fragmentos também.
fonte
O problema que penso é que a visão ainda é a atividade, não o fragmento. Os fragmentos não têm nenhuma visão independente própria e estão anexados à visão de atividades pai. É por isso que o evento termina na Atividade, não no fragmento. É lamentável, mas acho que você precisará de algum código para fazer isso funcionar.
O que tenho feito durante as conversões é simplesmente adicionar um ouvinte de clique que chama o manipulador de eventos antigo.
por exemplo:
fonte
Recentemente, resolvi esse problema sem precisar adicionar um método ao contexto Activity ou ter que implementar o OnClickListener. Não tenho certeza se é uma solução "válida" também, mas funciona.
Baseado em: https://developer.android.com/tools/data-binding/guide.html#binding_events
Isso pode ser feito com ligações de dados: basta adicionar sua instância de fragmento como uma variável e vincular qualquer método ao onClick.
E o código de ligação do fragmento seria ...
fonte
android:name="fragment" android:type="com.example.testapp.fragments.CustomFragment"/>
name
etype
davariable
tag não devem ter oandroid:
prefixo. Talvez exista uma versão antiga dos layouts do Android que exija isso?ButterKnife é provavelmente a melhor solução para o problema da desordem. Ele usa processadores de anotação para gerar o chamado código do "método antigo".
Mas o método onClick ainda pode ser usado, com um inflador personalizado.
Como usar
Implementação
fonte
Eu prefiro usar o tratamento de cliques no código do que usar o
onClick
atributo em XML ao trabalhar com fragmentos.Isso fica ainda mais fácil ao migrar suas atividades para fragmentos. Você pode simplesmente chamar o manipulador de cliques (definido anteriormente
android:onClick
em XML) diretamente de cadacase
bloco.Quando se trata de lidar com cliques em fragmentos, isso me parece mais simples do que
android:onClick
.fonte
Esta é outra maneira:
1.Crie um BaseFragment como este:
2.Use
ao invés de
3.Em sua atividade:
e
Espero que ajude.
fonte
No meu caso de uso, tenho 50 ImageViews ímpares que eu precisava conectar em um único método onClick. Minha solução é fazer um loop sobre as visualizações dentro do fragmento e definir o mesmo ouvinte onclick em cada:
fonte
A meu ver, as respostas são antigas. Recentemente, o Google introduziu o DataBinding, que é muito mais fácil de manipular ao clicar ou atribuir no seu xml.
Aqui está um bom exemplo, que você pode ver como lidar com isso:
Também há um tutorial muito bom sobre o DataBinding, que você pode encontrar aqui .
fonte
Você pode definir um retorno de chamada como um atributo do seu layout XML. O artigo Atributos XML personalizados para seus widgets personalizados do Android mostrará como fazer isso para um widget personalizado. O crédito vai para Kevin Dion :)
Estou investigando se posso adicionar atributos estilizados à classe Fragment base.
A idéia básica é ter a mesma funcionalidade que o View implementa ao lidar com o retorno de chamada onClick.
fonte
Adicionando à resposta de Blundell,
se você tiver mais fragmentos, com bastante onClicks:
Atividade:
Em seu fragmento:
fonte
Se você se registrar no xml usando android: Onclick = "", o retorno de chamada será dado à Atividade respeitada em cujo contexto seu fragmento pertence (getActivity ()). Se esse método não for encontrado na Atividade, o sistema lançará uma exceção.
fonte
Você pode considerar usar o EventBus para eventos dissociados. Você pode ouvir eventos com muita facilidade. Você também pode garantir que o evento esteja sendo recebido no thread da interface do usuário (em vez de chamar runOnUiThread .. para si mesmo para cada assinatura de evento)
https://github.com/greenrobot/EventBus
do Github:
fonte
Eu gostaria de acrescentar à resposta de Adjorn Linkz .
Se você precisar de vários manipuladores, poderá usar referências lambda
O truque aqui é que
handler
a assinatura do método corresponde àView.OnClickListener.onClick
assinatura. Dessa forma, você não precisará daView.OnClickListener
interface.Além disso, você não precisará de nenhuma declaração de chave.
Infelizmente, esse método é limitado apenas a interfaces que requerem um único método ou uma lambda.
fonte
Embora eu tenha encontrado algumas respostas legais baseadas na ligação de dados, não vi nada disso com essa abordagem - no sentido de permitir a resolução de fragmentos e permitir definições de layout sem fragmentos nos XMLs.
Supondo que a ligação de dados esteja ativada, aqui está uma solução genérica que posso propor; Um pouco longo, mas definitivamente funciona (com algumas ressalvas):
Etapa 1: implementação personalizada do OnClick
Isso executará uma pesquisa com reconhecimento de fragmentos nos contextos associados à visualização tocada (por exemplo, botão):
Etapa 2: aplicativo declarativo em arquivos de layout
Em seguida, nos XMLs com reconhecimento de ligação de dados:
Ressalvas
FragmentActivity
implementação baseada em 'moderna'fonte
Isso tem funcionado para mim: (Android studio)
fonte
Melhor solução IMHO:
no fragmento:
em seguida, no onViewStateRestored do Fragment:
fonte
Sua atividade está recebendo o retorno de chamada como deve ter sido usado:
Se você deseja que seu fragmento receba retorno de chamada, faça o seguinte:
e implementar
onClickListener
interface no Fragmentfonte