Se você ainda não utiliza Fragments ou não entende direito esse conceito, não escreva mais nenhuma linha de código antes de ler este artigo até o final.

O que você vai ver aqui vai mudar a sua visão sobre desenvolvimento Android e em como utilizar esse recurso extremamente poderoso.

Agora uma pergunta: Porque precisamos utilizar os Fragments?

Depois de ler este artigo até o final você vai conseguir responder a esta pergunta sem dificuldade nenhuma e também, vai conseguir utilizar este recurso sem maiores dificuldades.

Então, continue lendo este artigo e entenda de uma vez por todas o que é, como utilizar e quando utilizar os Fragments:

A Importância dos Fragments

Muita gente quando começa a pesquisar sobre Fragments imagina que esse recurso serve apenas para organizar e separar melhor os componentes de interface de um aplicativo Android.

Você provavelmente já se perguntou: porque usar Fragments? Onde usar? Usar em tudo?

Se quisermos, por exemplo, construir um layout agrupando as Views, não poderíamos apenas utilizar um ViewGroup? Ou talvez reutilizar um layout XML que já existe?

Com certeza poderíamos, mas o poder real dos Fragments vai muito além do agrupamento de elementos de interface.

Eles nos permitem modularisar nossas Activities, incluindo o ciclo de vida e os eventos que são utilizados em determinada interface.

Os Fragments foram introduzidos pela primeira vez na versão Honeycomb do Android para resolver um problema específico.

O Honeycomb foi a primeira versão do Android a suportar tablets e descobriram que a melhor maneira de criar excelentes interfaces para tablets, era colocar duas ou mais Activities uma ao lado das outras.

Por exemplo, se você tivesse um aplicativo com uma Activity de lista de itens, e quando clicasse em um item, abriria uma outra Activity com os detalhes.

Esse tipo de fluxo de telas é chamado de Master/Detail, que vai da listagem de itens até o detalhe do item escolhido.

Mas para tablets, uma boa interface desse tipo de fluxo, seria colocar essas duas Activities (lista e detalhe) uma ao lado da outra aproveitando o espaço na tela, como a imagem abaixo.

Agora, ao clicar em um item da lista, a Activity da direita é substituida por outra, ao invés de iniciar uma nova, como foi feito no exemplo do celular.

Mas infelizmente, o Android não suporta a incorporação de Activities dentro de outras Activties.

Até que os Fragments foram criados.

Um Fragment é um componente independente do Android que pode ser usado por uma Activity.

Os Fragments encapsulam funcionalidades para que seja mais fácil reutilizar dentro de outras Activties e layouts.

Como os Fragments Funcionam

Os Fragments são executados no contexto de uma Activity, mas tem seu próprio ciclo de vida e normalmente sua própria interface de usuário.

Então, se tratarmos os Fragments como pequenas Activities, cada um com seu próprio ciclo de vida independete, como isso se compara ao ciclo de vida de uma Activity real?

Os eventos básicos do ciclo de vida de um Fragment são muito semelhantes as de uma Activity que está incorporando o mesmo.

Caso não saiba como funciona o ciclo de vida de uma Activity, veja aqui.

E à medida que o ciclo de vida executa os eventos como onStart, onResume, onPause e onStop, esses mesmos eventos serão acionados dentro do próprio Fragment.

Assim, é possível mover a implementação feita nesses eventos da Activity para o Fragment sem muitos problemas, com algumas exceções.

Veja abaixo as diferenças entre o ciclo de vida de uma Activity e um Fragment.

OnCreateView

Ao invés de construir sua interface no onCreate, utilizamos o evento onCreateView do Fragment para isso.

O onCreateView é onde você constrói ou infla sua interface, faz conexão com alguma fonte de dados e retorna à Activity pai para poder integrá-lo em sua hierarquia de Views.

OnDestroyView

O onDestroyView é correspondente ao onDestroy da Activity e é chamado imediatamente antes do Fragment ser destruido. Ele funciona independente da Activity pai.

Aqui é onde você deve limpar quaisquer recursos especificamente relacionados à interface, como bitmaps na memória, cursores de dados, para garantir que não haja problemas de memória.

OnAttach

O onAttach é onde podemos obter uma referência para a Activity pai.

OnDetach

onDetach é a última coisa que acontece no ciclo de vida, mesmo após o seu Fragment ser tecnicamente destruído.

OnActivityCreated

Agora, a peça final do quebra-cabeça é onActivityCreated.

Isso notifica nosso Fragment que a Activity pai completou seu ciclo no onCreate e é aqui que podemos interagir com segurança com a interface de usuário.

OnStop

Assim como no ciclo de vida da Activity, uma vez que o Fragment não está mais visível, há uma chance dele ser encerrado.

Isso pode acontecer, após o onStop, no caso de a Activity ser encerrada, pois o Fragment faz parte da sua hierarquia de Views ou após o onDestroyView,

Como criar um Fragment

Para criar um Fragment você precisa estender a classe Fragment ou uma de suas subclasses.

As subclasses mais comuns utilizadas são, por exemplo, ListFragment, DialogFragment ou PreferenceFragmentCompat.

Mas atenção, no momento de importar a classe Fragment e suas subclasses, você vai encontrar implementações em pacotes diferentes: android.support.v4.appandroid.app.

Sempre de preferência para o android.support.v4.app.Fragment, que faz parte da biblioteca de suporte disponibilizada pelo Google com várias correções e suporte a versões antigas do Android.

Crie uma classe chamada MainFragment e estenda a classe Fragment do pacote android.support.v4.app.

import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.ViewGroup;

public class MainFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.main_fragment, container, false);
    }
}

Agora precisamos criar um layout XML para esse Fragment com o nome de main_fragment.xml.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Esse é um Fragment"/>

</LinearLayout>

Para unir o Fragment ao layout, basta implementar o método onCreateView() passando o ID do arquivo de layout criado.

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.layout.main_fragment, container, false);
}

Como adicionar o Fragment de forma estática

Para usar seu Fragment, você pode adicioná-lo estaticamente a um layout XML utilizando o componente <fragment>.

Os dois principais atributos desse componentes são:

  • class: Configura a classe do Fragment
  • tools:layout: Configura o layout do Fragment para renderizar no preview do Android Studio

Então, é só adicionar esse componente na sua Activity e configurar o Fragment.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools">
    <fragment
        android:id="@+id/mainFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="br.com.androidpro.meuapp.MainFragment"
        tools:layout="@layout/main_fragment">
    </fragment>

</LinearLayout>

E está pronto, já temos o Fragment configurado e pronto para ser utilizado na Activity.

Gerenciamento com FragmentManager

A classe FragmentManager permite que você adicione, remova e substitua Fragment no layout de sua Activity de forma dinâmica. Ele pode ser acessado em uma Activity através do método getSupportFragmentManager().

Assim como as classes e subclasses do Fragment, é recomendavél utilizar o FragmentManager e seus componentes do pacote de suporte android.support.v4.app.

A manipulação dinâmica de Fragments sempre deve ser feita utilizando uma transação através da classe FragmentTransaction.

Utilizando o FragmentManager

Dessa forma, para adicionar um Fragment a nossa Activity, não precisamos mais do componente <fragment> em nosso layout e podemos troca-lo por um FrameLayout.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <FrameLayout
        android:id="@+id/fragment_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

E usamos o FragmentManager para adicionar, substituir ou remover o Fragment dentro do FrameLayout.

// Pega o FragmentManager
FragmentManager fm = getSupportFragmentManager();

// Abre uma transação e adiciona
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.fragment_content, new MainFragment());
ft.commit();

// Substitui um Fragment
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragment_content, new MainFragment());
ft.commit();

// Remove um Fragment
Fragment fragment = fm.findFragmentById(R.id.fragment_content);
FragmentTransaction ft = fm.beginTransaction();
ft.remove(fragment);
ft.commit();

Passando parâmetros para os Fragments

Uma Activity pode utilizar um objeto da classe Bundle para passar informações e parâmetros para o Fragment.

MainFragment mainFragment = new MainFragment();

// Passando um link
Bundle bundle = new Bundle();
bundle.putString("link", link);
mainFragment.setArguments(bundle);

Então, dentro do Fragment podemos pegar essas informções no método onActivityCreated.

@Override
public void onActivityCreated(Bundle savedInstanceState) {
   super.onActivityCreated(savedInstanceState);
   Bundle bundle = getArguments();
   if (bundle != null) {
       String link = bundle.getString("link");
   }
}

Comunicação entre Fragments

Para aumentar a reutilização dos Fragments, eles nunca devem se comunicar diretamente uns com os outros. Toda comunicação deve ser feita através da Activity pai.

Para isso, um Fragment deve definir uma Interface interna. O Fragment requer que a Activity, que o usa, implemente essa Interface.

Desta forma você evita que o Fragment fique dependente da Acitivty que o usa.

No método onAttach(), você deve verificar se a Activity implementa corretamente essa Interface.

Por exemplo, suponha que você tenha um Fragment que precise se comunicar com outro Fragment ou com sua Activity pai quando um determinado item é selecionado.

Primeiro você defini uma Interface internamente no Fragment e implementa o método onAttach() para guardar uma instância da Interface e verificar a compatibilidade.

public class MainFragment extends Fragment {

    private OnItemSelectedListener listener;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.main_fragment, container, false);
    }

    public interface OnItemSelectedListener {
          public void onItemSelected(String link);
    }

    @Override
    public void onAttach(Context context) {
            super.onAttach(context);
            if (context instanceof OnItemSelectedListener) {
                    listener = (OnItemSelectedListener) context;
            } else {
                    throw new ClassCastException();
            }
    }
}

Depois, você deve implementar essa Interface na Activity.

public class MainACtivity extends Activity implements MainFragment.OnItemSelectedListener{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);
    }

    @Override
    public void onItemSelected(String link) {
        // Código que interague com outros componente, inclusive Fragments
    }

}

E no seu Fragment você pode utilizar o método onItemSelected() implementado pela Activity.

// Dispara o metodo implementado pela Activity
public void updateDetail(String link) {
    listener.onItemSelected(link);
}

Assim, conseguimos manter o baixo acoplamento entre o Fragment e outros componentes do aplicativo.

Fragments é só um tópico muito importante do elemento Interface Gráfica. Se quiser saber mais sobre esse e os outros elementos, inscreva-se e assista a nossa AULA GRATUITA: DESCUBRA OS 4 ELEMENTOS OBRIGATÓRIOS PARA VOCÊ SE TORNAR UM DESENVOLVEDOR ANDROID PROFISSIONAL E INDEPENDENTE…MESMO QUE VOCÊ NÃO SEJA UM GÊNIO DA PROGRAMAÇÃO.

Gostou do conteúdo sobre os Fragments?

Então compartilhe esse artigo com seus amigos e qualquer dúvida deixe nos comentários aqui em baixo.

Leia também


Fillipe Cordeiro
Fillipe Cordeiro

Engenheiro da computação e desenvolvedor de software a quase 10 anos, com experiência em tecnologias como Java, Python e Android. Agora, quero te ajudar a mergulhar no universo do Desenvolvimento Android.