Caso prefira, você encontrará todo esse material, em inglês, no site do Developer Android. A tradução e comentários dos materiais eu faço livremente para ajudar a comunidade que fala português.

sábado, 2 de abril de 2011

0 comentários

Interfaces de Usuários - Fragmentos Parte 01

Um fragmento representa um comportamento ou uma porção da interface de uma atividade. Você pode combinar multiplos fragmentos em uma atividade única para contruir uma interface multi-painel e reutilizar um fragmento em múltiplas atividades.Você pode combinar multiplos fragmentos em uma única atividade para construir uma interface multi painel e reutilizar um fragmento em multiplas atividades. Você pode pensar em um fragmento como uma seção modular de uma atividade, que tem seu próprio ciclo de vida, recebe seus próprios eventos de entrada e que você pode adicionar ou remover enquanto a atividade está sendo rodada.

Um fragmento sempre deve ser embarcado em uma atividade e o ciclo de vida dele é diretamente afetado pelo ciclo de vida da atividade que o hospeda. Por exemplo, quando uma atividade está pausada, também os fragmentos estão e quando uma atividade é destruída, os fragmentos vão junto com eles. Contudo, quando uma atividade está rodando, você pode manipular cada fragmento independentemente, como adicioná-los ou removê-los. Quando você realiza uma transação em um fragmento, você também pode inserí-lo no back stack que é gerenciado pela atividade - cada entrada no back stack na atividade é um registro de uma transação de fragmento que ocorreu. O back stack permite ao usuário retornar para o fragmento anterior, pressionando o botão BACK.

Quando você adiciona um fragmento como parte de seu layout de atividade, ele vive no ViewGroup dentro da hierarquia da atividade e define seu layout de views. Você pode inserir um fragmento dentro do layout da atividade declarando um fragmento no arquivo de layout de atividade, como no elemento <fragment>, ou de seu código de aplicação adicionando-o a um ViewGroup existente. Contudo, a um fragmento não é requerido ser parte de um layout de atividade; você pode usar um fragmento como um trabalhador invisível da atividade.

Esse documento descreve como construir sua aplicação para usar fragmentos incluindo como os fragmentos podem manter seu estado quando adicionado ao back stack da atividade, compartilhar eventos com a atividade e outros fragmentos na atividade, contribuir para a action bar da atividade e mais.

Filosofia do Design

O Android introduzio os fragmentos no Android 3.0 (API Level "Honeycomb"), primariamente para suportar designs de interface mais dinâmicos e flexíveis em telas mais largas, como tablets. Como a tela dos tablets é mais larga que a de smartphones, existe mais espaço para combinar e fazer o intercâmbio de interface. Fragmentos permitem tais designs sem a necessidade de você gerenciar mudanças complexas para a hierarquia da View. Dividindo o layout de uma atividade em fragmentos, você pode permitir a modificação da aparência em tempo de execução e preservar essas mudanças no back stack que é gerenciado pela atividade.

Por exemplo, uma aplicação de notícias pode usar um fragmento para mostrar uma lista de artigos na esquerda e um outro fragmento para mostrar um artigo na direita, ambos os fragmentos aparecendo em uma única atividade, lado a lado, e cada fragmento tendo seus próprios métodos de ciclo de vida  e que possa gerenciar suas próprias interações com o usuário. Ou seja, ao invés de usar uma única atividade para selecionar um artigo e outra atividade para lê-lo, o usuário pode selecionar um artigo e lê-lo dentro da mesma atividade, como ilustrado abaixo:



Um fragmento pode ser modular e reutilizável em sua aplicação. Ou seja, já que o fragmento define seu próprio layout e seu comportamento usando seus próprios métodos callback do ciclo de vida, você pode incluir um fragmento em múltiplas atividades. Isso é especialmente importante já que permite que você adapte a experiência do usuário em diferentes tamanhos de tela. Por exemplo, você pode incluir multiplos fragmentos em uma atividade apenas quando a tela é grande o suficiente ou, quando é pequena, lançar as atividades de maneira separada para usar os diferentes fragmentos.

Por exemplo - para continuar com a aplicação de notícias citada acima - a aplicação pode embarcar dois fragmentos na atividade A, quando rodando em uma tela larga, como a de um tablet. Mas, em uma tela de tamanho normal, como a de um smartphone, não há espaço suficiente para ambos os fragmentos, então a atividade A inclui apenas o fragmento para a lista de artigos e quando o usuário seleciona um artigo, ele inicia a atividade B, que inclui o fragmento para ler o artigo.

Criando um fragmento

Para criar um fragmento, você deve criar um Fragment (ou uma subclasse existente dela). A classe Fragment tem código que se parece muito com uma atividade. Ela contém métodos callback similares a uma atividade, como onCreate(), onStart(), onPause() e onStop(). De fato, se você estiver convertendo uma aplicação Android para usar fragmentos, você deve simplesmente mover os métodos de código callback de sua atividade para os métodos callback respectivos do seu fragmento.

Usualmente, você deveria implementar pelo menos os seguintes métodos:

onCreate()
O sistema chama esse método quando está criando o fragmento. Dentro de sua implementação, você deve inicializar os componentes essenciais do fragmento para que ele possa ser pausado, parado e então reiniciado.

onCreateView()
O sistema chama quando é hora do fragmento ser desenhado na interface pela primeira vez. Para desenhar a interface do seu fragmento, você deve retornar uma View de seu método que é a raiz do layout dos fragmentos. Você pode retornar null se o fragmento não provê uma interface.

onPause()
O sistema chama esse método como a primeira indicação que o usuário está deixando o fragmento (o que não quer dizer que ele esteja sendo destruído). É usualmente onde você deve fazer o commit de quaisquer dados que devam ser salvos, já que o usuário poderá não voltar a esse fragmento.

A maioria das aplicações devem implementar pelo menos esses três métodos para cada fragmento, mas existem outros métodos callback que você também deve usar para gerenciar os vários estágios do ciclo de vida do fragmento. Existem algumas subclasses que você pode querer extender ao invés de usar a classe base Fragment:

DialogFragment
Mostra um diálogo flutuante. Usando essa classe para criar um diálogo é uma boa alternativa a usar os métodos de ajuda de diálogo na classe Activity, já que você pode incorporar um diálogo de fragmento no back stack de fragmentos gerenciados pela atividade, permitindo ao usuário retornar para um fragmento anterior.

ListFragment
Mostra uma lista de itens que são gerenciados por um adaptador (como um SimpleCursorAdapter), similar ao ListActivity. Ele provê vários métodos para gerenciar uma list view, como o onListItemClick que pode ser chamado para gerenciar eventos de click.


PreferenceFragment
Mostra a hierarquia do objeto Preference como uma lista, similar a Preferencectivity. É útil quando está criando uma atividade de configuração para sua aplicação.


Adicionando uma interface de usuário

Um fragmento é usualmente usado como parte da interface de usuário da atividade e contribui com seu próprio layout para a atividade.

Para prover um layout para um fragmento, você deve implementar o método onCreateView, que é o método que o sistema Android chama quando é hora do fragmento ser desenhado na tela. Sua implementação desse método retorna uma View que é a raiz do layout do fragmento.

Nota: Se seu fragmento é uma subclasse de ListFragment, a implementação padrão retorna um ListView de onCreateView() e, por isso, você não precisará implementá-lo.

Para retornar um layout do onCreateView(), você pode inflá-lo a partir de um recurso de layout definido no XML. Para ajudá-lo o onCreateView provê o objeto de LayoutInflater.

Por exemplo, aqui está uma subclasse de Fragment que carrega o layout a partir do arquivo example_fragment.xml.

public static class ExampleFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Infla o layout para esse fragmento.
        return inflater.inflate(R.layout.example_fragment, container, false);
    }
}
O parâmetro de container passado para o onCreateView é o ViewGroup pai no qual o layout do fragmento deverá ser inserido. O parâmetro savedInstanceState é o Bundle que provê dados sobre a instância anterior do fragmento, se o fragmento está sendo recuperado.

O método inflate() recebe três argumentos:

  • O ID do recurso de layout que você deseja inflar.
  • O ViewGroup que será o pai do layout inflado. Passar o container é importante para que o sistema possa aplicar os parâmetros de layout para a View rais do layout inflado, especificado pela View pai na qual ele está sendo inflado.
  • Um argumento booleano indicando se o layout inflado deve ser anexado ao ViewGroup durante o processo de inflagem. Nesse caso, é falso pois o sistema já está inserindo o layout inflado dentro do container e passar um valor true faria com que fosse criado um viewgroup redundante no layout final.
Adicionando um fragmento a uma atividade

Normalmente, um fragmento contribui com uma porção da interface da aplicação que o hospeda, que é embarcado como parte da hierarquia geral da atividade. Existem duas maneiras com as quais você pode adicionar um fragmento a um layout de atividade:

Declarando um fragmento dentro do arquivo de layout da atividade

Nesse caso, você pode especificar as propriedades do layout para o fragmento como se ele fosse uma View.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <fragment android:name="com.example.news.ArticleListFragment"
            android:id="@+id/list"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
    <fragment android:name="com.example.news.ArticleReaderFragment"
            android:id="@+id/viewer"
            android:layout_weight="2"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
</LinearLayout>

O atributo android:name dentro de <fragment> especifica a classe Fragment que instancia o layout.

Quando o sistema cria um layout de atividade, ele instancia cada fragmento especificado no layout e chama os métodos onCreateView() de cada um deles para retornar o layout do fragmento. O sistema insere a View retornada pelo fragmento diretamente no local do elemento <fragment>.

Nota: Cada fragmento requer um identificador único para que o sistema possa usá-lo para restaurar o fragmento se a atividade for reiniciada (e que você pode usar para capturar o fragmento para realizar transações). Existem três maneiras de você prover um ID para um fragmento:

  • Suprir o atributo android:id com um ID único
  • Suprir o atributo android:tag com um nome de ID em formato string e único
  • Se você não prover nenhum desses IDs acima, o sistema usa o ID da View que contém o fragmento.
Programaticamente adicionando o fragmento a um ViewGroup existente

Em qualquer momento enquando a atividade está rodando, você pode adicionar fragmentos para o layout de atividades. Você simplesmente precisa especificar um ViewGroup no qual quer colocar o fragmento.

Para fazer transações de fragmento em sua atividade (como adicionar, remover ou substituir fragmentos), você deve usar APIs do FragmentTransaction. Você pode conseguir uma instância do FragmentTransaction a partir de sua Activity usando o código abaixo:
FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Você pode então adicionar o fragmento usando o método add(), especificando o fragmento a adicionar e a View no qual quer inserí-lo.
ExampleFragment fragment = new ExampleFragment();fragmentTransaction.add(R.id.fragment_container, fragment);fragmentTransaction.commit();
O primeiro argumento passado para o método add() é o ViewGroup no qual o fragmento deverá ser inserido, especificado pelo ID do recurso e o segundo parâmetro é o fragmento em si.

Uma vez que você tiver feito as mudanças com o FragmentTransactions, você deve chamar o método commit() para que as mudanças tenham efeito.

Adicionando um fragmento que não tem Interface

Os exemplos acima mostram como adiciona um fragmento para a sua atividade para que seja provido uma interface. Contudo, você também querer usar um fragmento para prover um comportamento de background para a atividade sem apresentar interfaces adicionais.

Para adicionar um fragmento que não tem interface, adiciona o fragmento para a atividade usando add(Fragment, String). Esse método adiciona o fragmento mas, como não está associado a uma view no layout da atividade, não recebe a chamada para onCreateView(). Então não há a necessidade de se implementar esse método.

Suprindo uma string tag para o fragmento não é algo que só possa ser feito para fragmentos que não tenham interface - você também pode prover string tags para fragmentos que contenham interface - mas se o fragmento não tem interface, então a string é a única maneira de identificá-lo. Se você deseja capturar o fragmento dentro da atividade, você pode precisar usar o findFragmentByTab().

Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.
Related Posts Plugin for WordPress, Blogger...