Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Para criar um Fragmento, uma classe deve herdar de Android.App.Fragment
e substituir o OnCreateView
método . OnCreateView
será chamado pela Atividade de hospedagem quando for hora de colocar o Fragmento na tela e retornará um View
. Um típico OnCreateView
criará isso View
inflando um arquivo de layout e anexando-o a um contêiner pai. As características do contêiner são importantes, pois o Android aplicará os parâmetros de layout do pai à interface do usuário do Fragmento. O exemplo a seguir ilustra isso:
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.Inflate(Resource.Layout.Example_Fragment, container, false);
}
O código acima inflará a exibição Resource.Layout.Example_Fragment
e a adicionará como uma exibição filho ao ViewGroup
contêiner.
Observação
As subclasses de fragmento devem ter um construtor sem argumento padrão público.
Adicionando um fragmento a uma atividade
Há duas maneiras pelas quais um fragmento pode ser hospedado dentro de uma atividade:
Declarativamente – fragmentos podem ser usados declarativamente dentro
.axml
de arquivos de layout usando a<Fragment>
marca .Programaticamente – os fragmentos também podem ser instanciados dinamicamente usando a
FragmentManager
API da classe.
O uso programático por meio da FragmentManager
classe será discutido posteriormente neste guia.
Usando um fragmento declarativamente
Adicionar um Fragmento dentro do layout requer o uso da <fragment>
marca e, em seguida, identificar o Fragmento fornecendo o class
atributo ou o android:name
atributo . O snippet a seguir mostra como usar o class
atributo para declarar um fragment
:
<?xml version="1.0" encoding="utf-8"?>
<fragment class="com.xamarin.sample.fragments.TitlesFragment"
android:id="@+id/titles_fragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
Este próximo snippet mostra como declarar um fragment
usando o android:name
atributo para identificar a classe Fragment :
<?xml version="1.0" encoding="utf-8"?>
<fragment android:name="com.xamarin.sample.fragments.TitlesFragment"
android:id="@+id/titles_fragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
Quando a Atividade estiver sendo criada, o Android criará uma instância de cada Fragmento especificado no arquivo de layout e inserirá o modo de OnCreateView
exibição criado no lugar do Fragment
elemento .
Os fragmentos que são adicionados declarativamente a uma Atividade são estáticos e permanecerão na Atividade até que ela seja destruída; não é possível substituir ou remover dinamicamente esse fragmento durante o tempo de vida da Atividade à qual ele está anexado.
Cada fragmento deve receber um identificador exclusivo:
android:id – assim como acontece com outros elementos da interface do usuário em um arquivo de layout, essa é uma ID exclusiva.
android:tag – esse atributo é uma cadeia de caracteres exclusiva.
Se nenhum dos dois métodos anteriores for usado, o Fragmento assumirá a ID da exibição de contêiner. No exemplo a seguir, em que nem android:id
nem android:tag
é fornecido, o Android atribuirá a ID fragment_container
ao Fragmento:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="+@id/fragment_container"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment class="com.example.android.apis.app.TitlesFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Caso do nome do pacote
O Android não permite caracteres maiúsculos em nomes de pacote; ele gerará uma exceção ao tentar inflar o modo de exibição se um nome de pacote contiver um caractere maiúsculo. No entanto, o Xamarin.Android é mais tolerante e tolerará caracteres maiúsculos no namespace.
Por exemplo, ambos os snippets a seguir funcionarão com o Xamarin.Android. No entanto, o segundo snippet fará com que um android.view.InflateException
seja gerado por um aplicativo Android baseado em Java puro.
<fragment class="com.example.DetailsFragment" android:id="@+id/fragment_content" android:layout_width="match_parent" android:layout_height="match_parent" />
OU
<fragment class="Com.Example.DetailsFragment" android:id="@+id/fragment_content" android:layout_width="match_parent" android:layout_height="match_parent" />
Ciclo de vida do fragmento
Os fragmentos têm seu próprio ciclo de vida que é um pouco independente, mas ainda afetado pelo ciclo de vida da Atividade de hospedagem. Por exemplo, quando uma Atividade é pausada, todos os fragmentos associados são pausados. O diagrama a seguir descreve o ciclo de vida do Fragmento.
Métodos de ciclo de vida de criação de fragmentos
A lista a seguir mostra o fluxo dos vários retornos de chamada no ciclo de vida de um Fragmento conforme ele está sendo criado:
OnInflate()
– Chamado quando o fragmento está sendo criado como parte de um layout de exibição. Isso pode ser chamado imediatamente depois que o fragmento é criado declarativamente de um arquivo de layout XML. O Fragmento ainda não está associado à atividade, mas a Atividade, o Pacote e o AttributeSet da hierarquia de exibição são passados como parâmetros. Esse método é melhor usado para analisar o AttributeSet e para salvar os atributos que podem ser usados posteriormente pelo Fragmento.OnAttach()
– Chamado depois que o Fragmento é associado à Atividade. Esse é o primeiro método a ser executado quando o Fragmento está pronto para ser usado. Em geral, fragmentos não devem implementar um construtor nem substituir o construtor padrão. Todos os componentes necessários para o Fragmento devem ser inicializados nesse método.OnCreate()
– Chamado pela atividade para criar o fragmento. Quando esse método é chamado, a hierarquia de exibição da Atividade de hospedagem pode não ser completamente instanciada, portanto, o Fragmento não deve depender de nenhuma parte da hierarquia de exibição da Atividade até mais tarde no ciclo de vida do Fragmento. Por exemplo, não use esse método para executar ajustes ou ajustes na interface do usuário do aplicativo. Este é o primeiro momento em que o Fragmento pode começar a coletar os dados necessários. O Fragmento está em execução no thread da interface do usuário neste ponto, portanto, evite qualquer processamento longo ou execute esse processamento em um thread em segundo plano. Esse método poderá ser ignorado se SetRetainInstance(true) for chamado. Essa alternativa será descrita mais detalhadamente abaixo.OnCreateView()
– Cria o modo de exibição para o Fragmento. Esse método é chamado quando o método OnCreate() da atividade é concluído. Neste ponto, é seguro interagir com a hierarquia de exibição da Atividade. Esse método deve retornar a exibição que será usada pelo Fragmento.OnActivityCreated()
– Chamado após Activity.OnCreate ter sido concluído pela Atividade de hospedagem. Os ajustes finais na interface do usuário devem ser executados no momento.OnStart()
– Chamado depois que a atividade que contém foi retomada. Isso torna o Fragmento visível para o usuário. Em muitos casos, o Fragmento conterá código que, de outra forma, estaria no método OnStart() de uma Atividade.OnResume()
– Esse é o último método chamado antes que o usuário possa interagir com o Fragmento. Um exemplo do tipo de código que deve ser executado nesse método seria habilitar recursos de um dispositivo com o qual o usuário pode interagir, como a câmera que o local atende. No entanto, serviços como esses podem causar consumo excessivo de bateria, e um aplicativo deve minimizar seu uso para preservar a duração da bateria.
Métodos de ciclo de vida de destruição de fragmentos
A próxima lista explica os métodos de ciclo de vida chamados como fragmentos que estão sendo destruídos:
OnPause()
– O usuário não pode mais interagir com o Fragmento. Essa situação existe porque alguma outra operação fragmentada está modificando esse Fragmento ou a Atividade de hospedagem está em pausa. É possível que a Atividade que hospeda esse Fragmento ainda esteja visível, ou seja, a Atividade em foco seja parcialmente transparente ou não ocupe a tela inteira. Quando esse método se torna ativo, é a primeira indicação de que o usuário está deixando o Fragmento. O Fragmento deve salvar todas as alterações.OnStop()
– O fragmento não está mais visível. A Atividade do host pode ser interrompida ou uma operação Fragment está modificando-a na Atividade. Esse retorno de chamada tem a mesma finalidade que Activity.OnStop.OnDestroyView()
– Esse método é chamado para limpo recursos associados à exibição. Isso é chamado quando a exibição associada ao fragmento foi destruída.OnDestroy()
– Esse método é chamado quando o fragmento não está mais em uso. Ele ainda está associado à Atividade, mas o Fragmento não é mais funcional. Esse método deve liberar todos os recursos que estão em uso pelo Fragmento, como um SurfaceView que pode ser usado para uma câmera. Esse método poderá ser ignorado se SetRetainInstance(true) for chamado. Essa alternativa será descrita mais detalhadamente abaixo.OnDetach()
– Esse método é chamado logo antes que o Fragmento não esteja mais associado à Atividade. A hierarquia de exibição do Fragmento não existe mais e todos os recursos usados pelo Fragmento devem ser liberados neste ponto.
Usando SetRetainInstance
É possível que um Fragmento especifique que ele não deve ser completamente destruído se a Atividade estiver sendo recriada. A Fragment
classe fornece o método SetRetainInstance
para essa finalidade. Se true
for passado para esse método, quando a Atividade for reiniciada, a mesma instância do Fragmento será usada. Se isso acontecer, todos os métodos de retorno de chamada serão invocados, exceto os retornos de chamada do OnCreate
ciclo de vida e OnDestroy
. Esse processo é ilustrado no diagrama de ciclo de vida mostrado acima (pelas linhas pontilhadas verdes).
Gerenciamento de Estado de Fragmento
Os fragmentos podem salvar e restaurar seu estado durante o ciclo de vida do fragmento usando uma instância de um Bundle
. O Pacote permite que um Fragmento salve dados como pares chave/valor e é útil para dados simples que não exigem muita memória. Um fragmento pode salvar seu estado com uma chamada para OnSaveInstanceState
:
public override void OnSaveInstanceState(Bundle outState)
{
base.OnSaveInstanceState(outState);
outState.PutInt("current_choice", _currentCheckPosition);
}
Quando uma nova instância de um Fragmento é criada, o estado salvo no Bundle
ficará disponível para a nova instância por meio dos OnCreate
métodos , OnCreateView
e OnActivityCreated
da nova instância.
O exemplo a seguir demonstra como recuperar o valor current_choice
do Bundle
:
public override void OnActivityCreated(Bundle savedInstanceState)
{
base.OnActivityCreated(savedInstanceState);
if (savedInstanceState != null)
{
_currentCheckPosition = savedInstanceState.GetInt("current_choice", 0);
}
}
OnSaveInstanceState
Substituir é um mecanismo apropriado para salvar dados transitórios em um Fragmento entre alterações de orientação, como o current_choice
valor no exemplo acima. No entanto, a implementação padrão de OnSaveInstanceState
cuida do salvamento de dados transitórios na interface do usuário para cada exibição que tenha uma ID atribuída. Por exemplo, examine um aplicativo que tem um EditText
elemento definido em XML da seguinte maneira:
<EditText android:id="@+id/myText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
Como o EditText
controle tem um id
atribuído, o Fragmento salva automaticamente os dados no widget quando OnSaveInstanceState
é chamado.
Limitações do pacote
Embora o uso OnSaveInstanceState
do torne mais fácil salvar dados transitórios, o uso desse método tem algumas limitações:
Se o Fragmento não for adicionado à pilha traseira, seu estado não será restaurado quando o usuário pressionar o botão Voltar .
Quando o Pacote é usado para salvar dados, esses dados são serializados. Isso pode levar a atrasos de processamento.
Contribuindo para o menu
Os fragmentos podem contribuir com itens para o menu de sua Atividade de hospedagem. Uma Atividade manipula os itens de menu primeiro. Se a Atividade não tiver um manipulador, o evento será passado para o Fragmento, que o manipulará.
Para adicionar itens ao menu da Atividade, um Fragmento deve fazer duas coisas.
Primeiro, o Fragmento deve implementar o método OnCreateOptionsMenu
e colocar seus itens no menu, conforme mostrado no seguinte código:
public override void OnCreateOptionsMenu(IMenu menu, MenuInflater menuInflater)
{
menuInflater.Inflate(Resource.Menu.menu_fragment_vehicle_list, menu);
base.OnCreateOptionsMenu(menu, menuInflater);
}
O menu no snippet de código anterior é inflado do seguinte XML, localizado no arquivo menu_fragment_vehicle_list.xml
:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/add_vehicle"
android:icon="@drawable/ic_menu_add_data"
android:title="@string/add_vehicle" />
</menu>
Em seguida, o Fragmento deve chamar SetHasOptionsMenu(true)
. A chamada para esse método anuncia ao Android que o Fragmento tem itens de menu para contribuir com o menu de opções. A menos que a chamada para esse método seja feita, os itens de menu do Fragmento não serão adicionados ao menu de opções da Atividade. Isso normalmente é feito no método OnCreate()
de ciclo de vida , conforme mostrado no próximo snippet de código:
public override void OnCreate(Bundle savedState)
{
base.OnCreate(savedState);
SetHasOptionsMenu(true);
}
A tela a seguir mostra a aparência desse menu: