Estendendo o exemplo RecyclerView
O aplicativo básico descrito em A Basic RecyclerView Example na verdade não faz muito – ele simplesmente rola e exibe uma lista fixa de itens de fotografia para facilitar a navegação. Em aplicativos do mundo real, os usuários esperam poder interagir com o aplicativo tocando em itens na tela. Além disso, a fonte de dados subjacente pode ser alterada (ou alterada pelo aplicativo) e o conteúdo da exibição deve permanecer consistente com essas alterações. Nas seções a seguir, você aprenderá a lidar com eventos de clique em itens e atualizar RecyclerView
quando a fonte de dados subjacente for alterada.
Manipulando eventos de clique no item
Quando um usuário toca em um item no , um evento de clique no RecyclerView
item é gerado para notificar o aplicativo sobre qual item foi tocado. Esse evento não é gerado por RecyclerView
– em vez disso, o modo de exibição de item (que é encapsulado no suporte de exibição) detecta toques e relata esses toques como eventos de clique.
Para ilustrar como manipular eventos de clique em item, as etapas a seguir explicam como o aplicativo básico de visualização de fotos é modificado para relatar qual fotografia foi tocada pelo usuário. Quando ocorre um evento de clique em item no aplicativo de exemplo, ocorre a seguinte sequência:
A fotografia detecta
CardView
o evento de clique no item e notifica o adaptador.O adaptador encaminha o evento (com informações de posição do item) para o manipulador de clique no item da atividade.
O manipulador de clique em item da atividade responde ao evento de clique em item.
Primeiro, um membro do manipulador de eventos chamado ItemClick
é adicionado à definição de PhotoAlbumAdapter
classe:
public event EventHandler<int> ItemClick;
Em seguida, um método de manipulador de eventos item-click é adicionado ao MainActivity
.
Esse manipulador exibe brevemente uma notificação do sistema que indica qual item de fotografia foi tocado:
void OnItemClick (object sender, int position)
{
int photoNum = position + 1;
Toast.MakeText(this, "This is photo number " + photoNum, ToastLength.Short).Show();
}
Em seguida, uma linha de código é necessária para registrar o OnItemClick
manipulador com PhotoAlbumAdapter
. Um bom lugar para fazer isso é imediatamente após PhotoAlbumAdapter
a criação:
mAdapter = new PhotoAlbumAdapter (mPhotoAlbum);
mAdapter.ItemClick += OnItemClick;
Neste exemplo básico, o registro do manipulador ocorre no método da atividade principal, mas um aplicativo de OnCreate
produção pode registrar o manipulador e OnResume
cancelá-lo – OnPause
consulte Ciclo de vida da atividade para obter mais informações.
PhotoAlbumAdapter
agora OnItemClick
chamará quando receber um evento de clique no item. A próxima etapa é criar um manipulador no adaptador que gera esse ItemClick
evento. O seguinte método, OnClick
, é adicionado imediatamente após o método do ItemCount
adaptador:
void OnClick (int position)
{
if (ItemClick != null)
ItemClick (this, position);
}
Esse OnClick
método é o ouvinte do adaptador para eventos de clique em item de exibições de item. Antes que esse ouvinte possa ser registrado com um modo de exibição de item (por meio do suporte de exibição do modo de exibição de item), o PhotoViewHolder
construtor deve ser modificado para aceitar esse método como um argumento adicional e registrar OnClick
com o evento de exibição Click
de item.
Aqui está o construtor modificado PhotoViewHolder
:
public PhotoViewHolder (View itemView, Action<int> listener)
: base (itemView)
{
Image = itemView.FindViewById<ImageView> (Resource.Id.imageView);
Caption = itemView.FindViewById<TextView> (Resource.Id.textView);
itemView.Click += (sender, e) => listener (base.LayoutPosition);
}
O itemView
parâmetro contém uma referência ao CardView
que foi tocado pelo usuário. Observe que a classe base do titular do modo de exibição sabe a posição de layout do item (CardView
) que ele representa (por meio da LayoutPosition
propriedade), e essa posição é passada para o método do OnClick
adaptador quando ocorre um evento de clique no item. O método do OnCreateViewHolder
adaptador é modificado para passar o método do OnClick
adaptador para o construtor do suporte de exibição:
PhotoViewHolder vh = new PhotoViewHolder (itemView, OnClick);
Agora, quando você cria e executa o aplicativo de visualização de fotos de amostra, tocar em uma foto na tela fará com que uma notificação do sistema apareça informando qual fotografia foi tocada:
Este exemplo demonstra apenas uma abordagem para implementar manipuladores de eventos com RecyclerView
o . Outra abordagem que pode ser usada aqui é colocar eventos no suporte de exibição e fazer com que o adaptador assine esses eventos. Se o aplicativo de foto de amostra fornecesse um recurso de edição de fotos, eventos separados seriam necessários para o ImageView
e dentro de TextView
cada CardView
: toca no TextView
iniciaria uma EditView
caixa de diálogo que permite ao usuário editar a legenda e tocaria na ImageView
ferramenta iniciaria um retoque de foto que permite ao usuário cortar ou girar a foto. Dependendo das necessidades do seu aplicativo, você deve projetar a melhor abordagem para lidar e responder a eventos de toque.
Para demonstrar como RecyclerView
pode ser atualizado quando o conjunto de dados é alterado, o aplicativo de visualização de fotos de exemplo pode ser modificado para escolher aleatoriamente uma foto na fonte de dados e trocá-la pela primeira foto. Primeiro, um botão Escolha aleatória é adicionado ao layout Main.axml do aplicativo de fotos de exemplo:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:id="@+id/randPickButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Random Pick" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:scrollbars="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
Em seguida, o código é adicionado no final do método da atividade OnCreate
principal para localizar o Random Pick
botão no layout e anexar um manipulador a ele:
Button randomPickBtn = FindViewById<Button>(Resource.Id.randPickButton);
randomPickBtn.Click += delegate
{
if (mPhotoAlbum != null)
{
// Randomly swap a photo with the first photo:
int idx = mPhotoAlbum.RandomSwap();
}
};
Esse manipulador chama o método do álbum de RandomSwap
fotos quando o botão Seleção aleatória é tocado. O RandomSwap
método troca aleatoriamente uma foto pela primeira foto na fonte de dados e, em seguida, retorna o índice da foto trocada aleatoriamente. Quando você compila e executa o aplicativo de exemplo com esse código, tocar no botão Seleção aleatória não resulta em uma alteração de exibição porque o RecyclerView
não está ciente da alteração na fonte de dados.
Para se manter RecyclerView
atualizado após as alterações da fonte de dados, o manipulador de clique de Seleção Aleatória deve ser modificado para chamar o método do NotifyItemChanged
adaptador para cada item da coleção que foi alterado (nesse caso, dois itens foram alterados: a primeira foto e a foto trocada). Isso faz com RecyclerView
que a atualização de sua exibição seja consistente com o novo estado da fonte de dados:
Button randomPickBtn = FindViewById<Button>(Resource.Id.randPickButton);
randomPickBtn.Click += delegate
{
if (mPhotoAlbum != null)
{
int idx = mPhotoAlbum.RandomSwap();
// First photo has changed:
mAdapter.NotifyItemChanged(0);
// Swapped photo has changed:
mAdapter.NotifyItemChanged(idx);
}
};
Agora, quando o botão Seleção aleatória é tocado, RecyclerView
atualiza a exibição para mostrar que uma foto mais abaixo na coleção foi trocada pela primeira foto da coleção:
Claro, poderia ter sido chamado em vez de fazer as duas chamadas para NotifyItemChanged
, mas isso forçaria RecyclerView
a atualizar toda a coleção, NotifyDataSetChanged
mesmo que apenas dois itens da coleção tivessem mudado. Chamar NotifyItemChanged
é significativamente mais eficiente do que chamar NotifyDataSetChanged
.