Um Fragment é basicamente um pedaço de interface do usuário dentro de uma Activity, podendo ser usados vários fragmentos para compor uma tela de vários painéis, sendo que estes podem ser facilmente reutilizados em outras Activitys. Um Fragment é como uma seção modular de uma Activity, que possui seu próprio ciclo de vida e eventos de entrada. Um fragment pode ser adicionado e removido da activity em tempo de execução.

Um Fragment é sempre adicionado em uma Activity, sendo seus estados vinculados a esta, se a Activiy “mãe” for pausada, os fragments que estão dentro dela também o serão, quando uma Activity for destruída todos os fragments dela também serão. Porém quando uma activity estiver em execução cada fragment será processado de forma independente podendo ser adicionado, destruído ou substituído por outro, podendo ser colocado em uma pilha de retorno, permitindo o usuário retorná-la através do botão voltar.

É possível adicionar um fragment dentro de um arquivo de layout de uma activity utilizando um elemento <fragment> ou programaticamente colocando ele dentro de um elemento ViewGroup como um FrameLayout.

A finalidade da criação dos fragments foi principalmente para flexibilizar aplicações em tablets e celulares, onde por exemplo, uma aplicação em uma tela de tablet possui uma lista de itens na esquerda que ao ser clicado o conteúdo selecionado é visualizado na área da direita. Em uma tela de celular não existiria espaço suficiente para os dois componentes visuais lado a lado, sendo necessário exibir o conteúdo selecionado em uma nova activity. Nesta situação sem utilizar fragments deveríamos ter toda a lógica da tela replicada, mas utilizando fragments podemos colocar a lógica da listagem em um fragment e a visualização do conteúdo em outro e controlando via programação em que parte da interface cada deve ser carregado, por exemplo tendo arquivos de layout da Activity para tamanhos de telas diversos e utilizando qualificadores como layout-land(tela “deitada”, landscape), layout-large (telas grandes) , etc. E podemos testar via programação a orientação da tela, o que pode ser feito através de Activity.getResources().getConfiguration().orientation. que pode assumir os valor Configuration.Configuration.ORIENTATION_PORTRAIT ou Configuration.ORIENTATION_LANDSCAPE. Você pode ver um exemplo mais ou menos aqui.

Exemplo fragments com telas de tamanhos diferentes
Exemplo fragments com telas de tamanhos diferentes

Para criar um Fragment basta criar uma classe que estenda a classe Fragment, e sobreescrever o método onCreateView, que é responsável por retornar um View que será exibido no local designado na tela. Podemos construir este View através de um arquivo de layout xml e “inflá-lo” através do LayoutInflater recebido por parâmetro, adicionar eventos aos seus elementos como mostrado no exemplo abaixo.

package info.botecodigita.fragmentexemplo;
 
public static class ExemploFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
         
        View view = inflater.inflate(R.layout.example_fragment, container, false);
 
        Button bt = view.findViewById(R.id.bt);
 
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText( getActivity() , "Clicado BT Fragment" , Toast.LENGTH_LONG).show();
            }
        });
 
        return view;
    }
}

O arquivo de layout(res/layout/example_fragment.xml) para o fragment acima.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp">
 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Olá Fragment"
        android:layout_gravity="center"/>
 
 
 
    <TextView
        android:id="@+id/bt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Botão"
        android:layout_gravity="center"/>
 
</LinearLayout>

Agora para adicionar este fragment ao layout de uma Activity basta colocar uma tag <fragment> e no atributo android:name colocar o nome canônico da classe de fragment que criamos.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="info.botecodigital.exemplofragment.MainActivity">
 
    <fragment
        android:id="@+id/fragment"
        android:name="info.botecodigita.fragmentexemplo.ExemploFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:tag="TAG"
         />
</LinearLayout>

Outra alternativa é adicionar o fragment via programação, para isso adicionamos um elemento ViewGroup no layout da activity como um FrameLayout.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="info.botecodigital.exemplofragment.MainActivity">
 
    <FrameLayout
        android:id="@+id/fragment_exemplo"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:tag="TAG"
         />
</LinearLayout>

Depois será necessário usar a API de FragmentTransaction, já que é através dela que adicionamos, removemos e substituímos um fragment. Adquirimos uma instância de FragmentTransaction através de um objeto FragmentManager retornado pelo método getFragmentManager() da activity. Deste objeto fragmentTransaction podemos utilizar o método add para adicionar nosso fragment dentro do ViewGroup, sendo que o método add recebe como parâmetro um ID do ViewGroup ao qual o fragment será adicionado e o próprio objeto Fragment. Também podemos utilizar o método replace no lugar de add que irá substitui o fragment, se dentro do ViewGroup já contenha um. Após ser feita as operações em um fragment devemos chamar o método commit.

ExemploFragment fragment = new ExemploFragment();
 
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_exemplo, fragment);
fragmentTransaction.commit();

Para colocar um fragment adicionado na pilha de retorno e consequentemente podermos voltar a ela através do botão voltar do dispositivo, devemos chamar o método addToBackStack.

fragmentTransaction.addToBackStack(null)

That’s all folks!