ViewPager com fragmentos
ViewPager é um gerenciador de layout que permite implementar a navegação gestual. A navegação gestual permite que o usuário deslize para a esquerda e para a direita para percorrer páginas de dados. Este guia explica como implementar uma interface do usuário deslizável com ViewPager, usando Fragmentos como as páginas de dados.
Visão geral
ViewPager
é frequentemente usado em conjunto com fragmentos para que seja mais fácil gerenciar o ciclo de vida de cada página no ViewPager
. Neste passo a passo, ViewPager
é usado para criar um aplicativo chamado FlashCardPager que apresenta uma série de problemas matemáticos em cartões flash. Cada cartão flash é implementado como um fragmento. O usuário desliza para a esquerda e para a direita através dos cartões flash e toca em um problema de matemática para revelar sua resposta. Este aplicativo cria uma Fragment
instância para cada cartão flash e implementa um adaptador derivado do FragmentPagerAdapter
. Em Viewpager e Views, a maior parte do trabalho foi feita em MainActivity
métodos de ciclo de vida. No FlashCardPager, a maior parte do trabalho será feito por um Fragment
em um de seus métodos de ciclo de vida.
Este guia não aborda os conceitos básicos de fragmentos – se você ainda não estiver familiarizado com fragmentos no Xamarin.Android, consulte Fragmentos para ajudá-lo a começar a usar fragmentos.
Iniciar um projeto de aplicativo
Crie um novo projeto Android chamado FlashCardPager. Em seguida, inicie o Gerenciador de Pacotes NuGet (para obter mais informações sobre como instalar pacotes NuGet, consulte Demonstra Passo a passo: incluindo um NuGet em seu projeto). Encontre e instale o pacote Xamarin.Android.Support.v4 conforme explicado em Viewpager e Views.
Adicionar uma fonte de dados de exemplo
No FlashCardPager, a fonte de dados é um baralho de cartões flash representados pela FlashCardDeck
classe, essa fonte de dados fornece o conteúdo do ViewPager
item. FlashCardDeck
contém uma coleção pronta de problemas e respostas matemáticas. O FlashCardDeck
construtor não requer argumentos:
FlashCardDeck flashCards = new FlashCardDeck();
A coleção de cartões flash em FlashCardDeck
é organizada de tal forma que cada cartão flash pode ser acessado por um indexador. Por exemplo, a seguinte linha de código recupera o quarto problema de cartão flash no baralho:
string problem = flashCardDeck[3].Problem;
Esta linha de código recupera a resposta correspondente para o problema anterior:
string answer = flashCardDeck[3].Answer;
Como os detalhes de implementação de FlashCardDeck
não são relevantes para a compreensão ViewPager
, o código não está listado FlashCardDeck
aqui.
O código-fonte para FlashCardDeck
está disponível em FlashCardDeck.cs.
Baixe este arquivo de origem (ou copie e cole o código em um novo arquivo FlashCardDeck.cs ) e adicione-o ao seu projeto.
Criar um layout ViewPager
Abra Resources/layout/Main.axml e substitua seu conteúdo pelo seguinte XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</android.support.v4.view.ViewPager>
Esse XML define um que ocupa a ViewPager
tela inteira. Observe que você deve usar o nome totalmente qualificado android.support.v4.view.ViewPager porque ViewPager
é empacotado em uma biblioteca de suporte. ViewPager
está disponível apenas na Biblioteca de Suporte do Android v4, não está disponível no SDK do Android.
Configurar o ViewPager
Edite MainActivity.cs e adicione as seguintes using
instruções:
using Android.Support.V4.View;
using Android.Support.V4.App;
Altere a MainActivity
declaração de classe para que ela seja derivada de FragmentActivity
:
public class MainActivity : FragmentActivity
MainActivity
é derivado de (em vez deFragmentActivity
Activity
) porque FragmentActivity
sabe como gerenciar o suporte de fragmentos. Substitua o método OnCreate
pelo seguinte código:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
ViewPager viewPager = FindViewById<ViewPager>(Resource.Id.viewpager);
FlashCardDeck flashCards = new FlashCardDeck();
}
Este código faz o seguinte:
Define a exibição do recurso de layout Main.axml .
Recupera uma referência ao
ViewPager
do layout.Instancia um novo
FlashCardDeck
como a fonte de dados.
Quando você compila e executa esse código, você deve ver uma exibição semelhante à seguinte captura de tela:
Neste ponto, o ViewPager
está vazio porque faltam os fragmentos que são usados preencher o ViewPager
, e está faltando um adaptador para criar esses fragmentos a partir dos dados no FlashCardDeck.
Nas seções a seguir, um FlashCardFragment
é criado para implementar a funcionalidade de cada cartão flash e um FragmentPagerAdapter
é criado para conectar o ViewPager
aos fragmentos criados a partir de dados no FlashCardDeck
.
Criar o fragmento
Cada cartão flash será gerenciado por um fragmento de interface do usuário chamado FlashCardFragment
. FlashCardFragment
A visualização do exibirá as informações contidas em um único cartão flash. Cada instância do será hospedada FlashCardFragment
ViewPager
pelo .
FlashCardFragment
A exibição do consistirá em um TextView
que exibe o texto do problema do cartão flash. Essa exibição implementará um manipulador de eventos que usa um Toast
para exibir a resposta quando o usuário toca na pergunta do cartão flash.
Criar o layout FlashCardFragment
Antes FlashCardFragment
de ser implementado, seu layout deve ser definido. Esse layout é um layout de contêiner de fragmento para um único fragmento. Adicione um novo layout do Android a Recursos/layout chamado flashcard_layout.axml. Abra Resources/layout/flashcard_layout.axml e substitua seu conteúdo pelo seguinte código:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">
<TextView
android:id="@+id/flash_card_question"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textAppearance="@android:style/TextAppearance.Large"
android:textSize="100sp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="Question goes here" />
</RelativeLayout>
Este layout define um único fragmento de cartão flash; Cada fragmento é composto por um TextView
que exibe um problema matemático usando uma fonte grande (100sp). Este texto é centralizado vertical e horizontalmente no cartão flash.
Criar a classe FlashCardFragment inicial
Adicione um novo arquivo chamado FlashCardFragment.cs e substitua seu conteúdo pelo seguinte código:
using System;
using Android.OS;
using Android.Views;
using Android.Widget;
using Android.Support.V4.App;
namespace FlashCardPager
{
public class FlashCardFragment : Android.Support.V4.App.Fragment
{
public FlashCardFragment() { }
public static FlashCardFragment newInstance(String question, String answer)
{
FlashCardFragment fragment = new FlashCardFragment();
return fragment;
}
public override View OnCreateView (
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.Inflate (Resource.Layout.flashcard_layout, container, false);
TextView questionBox = (TextView)view.FindViewById (Resource.Id.flash_card_question);
return view;
}
}
}
Este código esboça a definição essencial Fragment
que será usada para exibir um cartão flash. Observe que FlashCardFragment
é derivado da versão da biblioteca de Fragment
suporte definida no Android.Support.V4.App.Fragment
. O construtor está vazio para que o newInstance
método de fábrica é usado para criar um novo FlashCardFragment
em vez de um construtor.
O OnCreateView
método de ciclo de vida cria e configura o TextView
. Ele infla o layout para o fragmento TextView
e retorna o inflado TextView
para o chamador. LayoutInflater
e ViewGroup
são passados para OnCreateView
que ele possa inflar o layout. O savedInstanceState
pacote contém dados que OnCreateView
são usados para recriar o TextView
de um estado salvo.
A visão do fragmento é explicitamente inflada pela chamada para inflater.Inflate
. O container
argumento é o pai do modo de exibição, e o false
sinalizador instrui o inflador a abster-se de adicionar o modo de exibição inflado ao pai do modo de exibição (ele será adicionado quando ViewPager
chamar o método do GetItem
adaptador mais adiante neste passo a passo).
Adicionar código de estado a FlashCardFragment
Como uma Atividade, um fragmento tem um Bundle
que ele usa para salvar e recuperar seu estado. No FlashCardPager, isso Bundle
é usado para salvar o texto de pergunta e resposta para o cartão flash associado. Em FlashCardFragment.cs, adicione as seguintes Bundle
chaves à parte superior da FlashCardFragment
definição de classe:
private static string FLASH_CARD_QUESTION = "card_question";
private static string FLASH_CARD_ANSWER = "card_answer";
Modifique o newInstance
método factory para que ele crie um Bundle
objeto e use as chaves acima para armazenar o texto de pergunta e resposta passado no fragmento depois que ele for instanciado:
public static FlashCardFragment newInstance(String question, String answer)
{
FlashCardFragment fragment = new FlashCardFragment();
Bundle args = new Bundle();
args.PutString(FLASH_CARD_QUESTION, question);
args.PutString(FLASH_CARD_ANSWER, answer);
fragment.Arguments = args;
return fragment;
}
Modifique o método OnCreateView
de ciclo de vida do fragmento para recuperar essas informações do pacote transmitido e carregar o texto da pergunta no TextBox
:
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
string question = Arguments.GetString(FLASH_CARD_QUESTION, "");
string answer = Arguments.GetString(FLASH_CARD_ANSWER, "");
View view = inflater.Inflate(Resource.Layout.flashcard_layout, container, false);
TextView questionBox = (TextView)view.FindViewById(Resource.Id.flash_card_question);
questionBox.Text = question;
return view;
}
A answer
variável não é usada aqui, mas será usada posteriormente quando o código do manipulador de eventos for adicionado a esse arquivo.
Criar o adaptador
ViewPager
usa um objeto de controlador de adaptador que fica entre a ViewPager
e a fonte de dados (consulte a ilustração no artigo Adaptador ViewPager).
Para acessar esses dados, ViewPager
é necessário que você forneça um adaptador personalizado derivado do PagerAdapter
. Como este exemplo usa fragmentos, ele usa um FragmentPagerAdapter
– FragmentPagerAdapter
é derivado de PagerAdapter
.
FragmentPagerAdapter
Representa cada página como uma Fragment
que é mantida persistentemente no gerenciador de fragmentos enquanto o usuário puder retornar à página. À medida que o usuário passa o dedo pelas páginas do ViewPager
, o FragmentPagerAdapter
extrai informações da fonte de dados e as usa para criar Fragment
s para a ViewPager
exibição.
Ao implementar um FragmentPagerAdapter
, você deve substituir o seguinte:
Count – propriedade somente leitura que retorna o número de exibições (páginas) disponíveis.
GetItem – Retorna o fragmento a ser exibido para a página especificada.
Adicione um novo arquivo chamado FlashCardDeckAdapter.cs e substitua seu conteúdo pelo seguinte código:
using System;
using Android.Views;
using Android.Widget;
using Android.Support.V4.App;
namespace FlashCardPager
{
class FlashCardDeckAdapter : FragmentPagerAdapter
{
public FlashCardDeckAdapter (Android.Support.V4.App.FragmentManager fm, FlashCardDeck flashCards)
: base(fm)
{
}
public override int Count
{
get { throw new NotImplementedException(); }
}
public override Android.Support.V4.App.Fragment GetItem(int position)
{
throw new NotImplementedException();
}
}
}
Esse código resume a implementação essencial FragmentPagerAdapter
. Nas seções a seguir, cada um desses métodos é substituído pelo código de trabalho. O objetivo do construtor é passar o gerenciador de fragmentos para o FlashCardDeckAdapter
construtor de classe base do .
Implementar o construtor adaptador
Quando o aplicativo instancia o FlashCardDeckAdapter
, ele fornece uma referência ao gerenciador de fragmentos e um arquivo FlashCardDeck
.
Adicione a seguinte variável de membro à parte superior da FlashCardDeckAdapter
classe em FlashCardDeckAdapter.cs:
public FlashCardDeck flashCardDeck;
Adicione a seguinte linha de código ao FlashCardDeckAdapter
construtor:
this.flashCardDeck = flashCards;
Essa linha de código armazena a FlashCardDeck
instância que o FlashCardDeckAdapter
será usado.
Implementar contagem
A Count
implementação é relativamente simples: ele retorna o número de cartões flash no baralho de cartões flash. Substitua Count
pelo seguinte código:
public override int Count
{
get { return flashCardDeck.NumCards; }
}
A NumCards
propriedade de retorna o número de cartões flash (número de fragmentos) no conjunto de FlashCardDeck
dados.
Implementar GetItem
O GetItem
método retorna o fragmento associado à posição fornecida. Quando GetItem
é chamado para uma posição no baralho de cartão flash, ele retorna um FlashCardFragment
configurado para exibir o problema do cartão flash nessa posição. Substitua o método GetItem
pelo seguinte código:
public override Android.Support.V4.App.Fragment GetItem(int position)
{
return (Android.Support.V4.App.Fragment)
FlashCardFragment.newInstance (
flashCardDeck[position].Problem, flashCardDeck[position].Answer);
}
Este código faz o seguinte:
Procura a cadeia de caracteres do problema matemático no
FlashCardDeck
deck para a posição especificada.Procura a posição especificada na cadeia de caracteres de resposta no
FlashCardDeck
deck.Chama o
FlashCardFragment
métodonewInstance
de fábrica, passando o problema do cartão flash e as cadeias de resposta.Cria e retorna um novo cartão
Fragment
flash que contém o texto de pergunta e resposta para essa posição.
Quando o ViewPager
renderiza o Fragment
at position
, ele exibe a TextBox
cadeia de caracteres do problema matemático que reside position
no baralho de cartões flash.
Adicionar o adaptador ao ViewPager
Agora que o FlashCardDeckAdapter
está implementado, é hora de adicioná-lo ao ViewPager
. Em MainActivity.cs, adicione a seguinte linha de código ao final do OnCreate
método:
FlashCardDeckAdapter adapter =
new FlashCardDeckAdapter(SupportFragmentManager, flashCards);
viewPager.Adapter = adapter;
Esse código instancia o FlashCardDeckAdapter
, passando o SupportFragmentManager
no primeiro argumento. (A SupportFragmentManager
propriedade de FragmentActivity é usada para obter uma referência ao – para obter mais informações sobre o FragmentManager
FragmentManager
, consulte Gerenciando fragmentos.)
A implementação principal agora está concluída – compile e execute o aplicativo. Você deve ver a primeira imagem do baralho de cartões flash aparecer na tela, como mostrado à esquerda na próxima captura de tela. Deslize para a esquerda para ver mais cartões flash e, em seguida, deslize para a direita para voltar pelo deck de cartões flash:
Adicionar um indicador de pager
Essa implementação mínima ViewPager
exibe cada cartão flash no baralho, mas não fornece nenhuma indicação de onde o usuário está dentro do baralho. O próximo passo é adicionar um PagerTabStrip
arquivo . O PagerTabStrip
informa ao usuário sobre qual número do problema é exibido e fornece contexto de navegação exibindo uma dica dos cartões flash anteriores e seguintes.
Abra Resources/layout/Main.axml e adicione um PagerTabStrip
ao layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.view.PagerTabStrip
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:textColor="#fff" />
</android.support.v4.view.ViewPager>
Ao criar e executar o aplicativo, você verá o vazio PagerTabStrip
exibido na parte superior de cada cartão flash:
Exibir um título
Para adicionar um título a cada guia de página, implemente o GetPageTitleFormatted
método no adaptador. ViewPager
chamadas GetPageTitleFormatted
(se implementadas) para obter a cadeia de caracteres de título que descreve a página na posição especificada. Adicione o seguinte método à FlashCardDeckAdapter
classe em FlashCardDeckAdapter.cs:
public override Java.Lang.ICharSequence GetPageTitleFormatted(int position)
{
return new Java.Lang.String("Problem " + (position + 1));
}
Esse código converte a posição no baralho de cartas flash em um número de problema. A cadeia de caracteres resultante é convertida em um Java String
que é retornado para o ViewPager
. Quando você executa o aplicativo com esse novo método, cada página exibe o número do problema no PagerTabStrip
:
Você pode deslizar para frente e para trás para ver o número do problema no baralho de cartões flash que é exibido na parte superior de cada cartão flash.
Manipular a entrada do usuário
FlashCardPager apresenta uma série de cartões flash baseados em fragmentos em um ViewPager
, mas ainda não tem uma maneira de revelar a resposta para cada problema. Nesta seção, um manipulador de eventos é adicionado ao FlashCardFragment
para exibir a resposta quando o usuário toca no texto do problema do cartão flash.
Abra FlashCardFragment.cs e adicione o seguinte código ao final do método antes que a OnCreateView
exibição seja retornada ao chamador:
questionBox.Click += delegate
{
Toast.MakeText(Activity.ApplicationContext,
"Answer: " + answer, ToastLength.Short).Show();
};
Esse Click
manipulador de eventos exibe a resposta em uma notificação do sistema que aparece quando o usuário toca no TextBox
. A answer
variável foi inicializada anteriormente quando as informações de estado foram lidas do Bundle que foi passado para OnCreateView
. Crie e execute o aplicativo e, em seguida, toque no texto do problema em cada cartão flash para ver a resposta:
O FlashCardPager apresentado neste passo a passo usa um MainActivity
derivado de FragmentActivity
, mas você também pode derivar MainActivity
de AppCompatActivity
(que também fornece suporte para gerenciar fragmentos).
Resumo
Este passo a passo forneceu um exemplo passo a passo de como criar um aplicativo baseado em básico ViewPager
usando Fragment
s. Ele apresentou uma fonte de dados de exemplo contendo perguntas e respostas de cartão flash, um ViewPager
layout para exibir os cartões flash e uma FragmentPagerAdapter
subclasse que conecta o ViewPager
à fonte de dados. Para ajudar o usuário a navegar pelos cartões flash, foram incluídas instruções que explicam como adicionar um para exibir o PagerTabStrip
número do problema na parte superior de cada página. Finalmente, o código de manipulação de eventos foi adicionado para exibir a resposta quando o usuário toca em um problema de cartão flash.