Suponha a seguinte Activity
com um Fragment
definidos de forma semelhante ao visto no curso:
public class MainActivity extends Activity {
public void onCreate() {
//...
UmFragment fragment = new UmFragment();
//...
transaction.replace(..., fragment);
}
public String getMetodoDaActivity() {
return "método da activity chamado";
}
}
public class UmFragment extends Fragment {
public View onCreateView(...) {
//...
MainActivity activity = (MainActivity) getActivity();
String detalhes = activity.getMetodoDaActivity();
}
}
Se UmFragment
for usado somente dentro de MainActivity
, podemos assumir que getActivity()
sempre devolverá uma instância de MainActivity
. Sem problemas até aí.
No entanto, devemos sempre pensar nos nossos componentes de tela de forma a torná-los mais reutilizáveis, e como Fragments representam pedaços (ou partes) da tela, esses pedaços podem ser reaproveitados em outras telas, em outras Activities.
Porém, como reaproveitaremos nosso UmFragment
se ele espera que getActivity()
devolva uma MainActivity
? Caso tentemos colocar esse fragment em outra activity, teremos um ClassCastException
.
Então, uma forma é estabelecer um contrato fixo entre todas as activities que poderão possuir UmFragment
. Esse contrato pode ser feito com uma interface!
public interface UmFragmentContainer {
}
Veja que lá no UmFragment
precisamos da MainActivity
para chamar o método getMetodoDaActivity()
. Esse método deverá, então, estar descrito na nossa interface:
public interface UmFragmentContainer {
public String getMetodoDaActivity();
}
Agora, todos que possuirem UmFragment
devem implementar essa interface:
public class MainActivity extends Activity implements UmFragmentContainter {
//Nada mudou aqui, pois esse método já existia aqui.
public String getMetodoDaActivity() {
return "método da activity chamado";
}
}
Agora, nosso fragment não precisa se preocupar com o cast para MainActivity
, basta fazer para UmFragmentContainer
:
public class UmFragment extends Fragment {
public View onCreateView(...) {
//...
UmFragmentContainer container = (UmFragmentContainer) getActivity();
String detalhes = container.getMetodoDaActivity();
}
}
Veja que, embora façamos um cast, não estamos acoplados com uma classe e sim com uma interface. Note que nosso fragment não sabe qual objeto nos dará a implementação concreta do método getMetodoDaActivity
. A única coisa que ele sabe é que a activity onde ele está inserido deve ser UmFragmentContainer
.
Essa é uma abordagem mais correta para se trabalhar com chamadas entre um fragment e uma activity.