Criar listas dinâmicas com a RecyclerView Parte do Android Jetpack.
O RecyclerView facilita e torna eficiente a exibição de grandes conjuntos de dados. Você fornece os dados e define a aparência de cada item, e a biblioteca RecyclerView, quando necessário, cria os elementos dinamicamente.
O RecyclerView, como o nome indica, recicla esses elementos individuais. Quando um item rola para fora da tela, o RecyclerView não destrói a visualização dele. Em vez disso, o RecyclerView reutiliza a visualização para novos itens que passaram a aparecer na tela. A RecyclerView melhora o desempenho e a capacidade de resposta do app, além de reduz o consumo de energia.
Classes principais
Várias classes funcionam juntas para criar sua lista dinâmica.
RecyclerView
é oViewGroup
que contém as visualizações correspondentes aos seus dados. Como essa é uma visualização em si, você adicionaRecyclerView
. ao layout da mesma forma que você adicionaria qualquer outro elemento da interface.Cada elemento individual da lista é definido por um objeto fixador de visualização. Quando o fixador de visualização é criado, ele não tem dados associados a si mesmo. Depois que o fixador de visualização é criado, o
RecyclerView
vincula-o a seus dados. Para definir o fixador de visualização, estendaRecyclerView.ViewHolder
.O
RecyclerView
solicita visualizações e vincula as visualizações aos próprios dados. chamando métodos no adaptador. Para definir o adaptador, estendaRecyclerView.Adapter
.O gerenciador de layout organiza os elementos individuais na sua lista. Você pode usar um dos gerenciadores de layout fornecidos pela biblioteca RecyclerView ou pode definir seu próprio gerenciador. Todos os gerenciadores de layout são baseados na classe abstrata
LayoutManager
da biblioteca.
Você pode conferir como todas as peças se encaixam no app de exemplo RecyclerView (Kotlin) (link em inglês) ou app de exemplo RecyclerView (Java).
Etapas para implementar o RecyclerView
Se você for usar a RecyclerView, há algumas coisas que precisa fazer. Eles são explicados em detalhes nas seções a seguir.
Decida a aparência da lista ou grade. Normalmente, você pode usar um dos gerenciadores de layout padrão da biblioteca RecyclerView.
Defina a aparência e o comportamento de cada elemento da lista. Com base nisso, estenda a classe
ViewHolder
. A versão doViewHolder
fornece toda a funcionalidade para os itens da lista. O fixador de visualização é um wrapper em torno de umaView
, e essa visualização é gerenciada porRecyclerView
.Defina o
Adapter
que associa seus dados às visualizaçõesViewHolder
.
Há também as opções avançadas de personalização, que permitem adaptar o RecyclerView de acordo com suas necessidades.
Planejar seu layout
Os itens na RecyclerView são organizados por uma classe
LayoutManager
. A biblioteca RecyclerView fornece três gerenciadores de layout, que processam as
situações de layout mais comuns:
LinearLayoutManager
organiza os itens em uma lista unidimensional.GridLayoutManager
organiza os itens em uma grade bidimensional:- Se a grade for organizada na vertical,
GridLayoutManager
tentará fazer com que todos os elementos em cada linha tenham a mesma largura e altura, mas linhas diferentes podem ter alturas diferentes. - Se a grade for organizada na horizontal,
GridLayoutManager
tentará fazer com que todos os elementos em cada coluna tenham a mesma largura e altura, mas colunas diferentes podem ter larguras diferentes.
- Se a grade for organizada na vertical,
StaggeredGridLayoutManager
é semelhante aGridLayoutManager
, mas não exige que os itens de uma linha tenham a mesma altura (para grades verticais) ou itens na mesma coluna tenham a mesma largura (para grades horizontais). O resultado é que os itens em uma linha ou coluna podem acabar afastados um do outro.
Você também precisa projetar o layout dos itens individuais. Você precisa disto ao projetar o fixador de visualização, conforme descrito na próxima seção.
Implementar o adaptador e o fixador de visualização
Depois de determinar o layout, é necessário implementar a Adapter
e
ViewHolder
. Essas duas classes trabalham juntas para definir como seus dados são
exibidos. O ViewHolder
é um wrapper em torno da View
que contém o
layout de um item individual na lista. O Adapter
cria ViewHolder
.
conforme necessário, além de definir os dados para essas visualizações. O processo de
associação de visualizações aos dados é chamado de vinculação.
Ao definir o adaptador, você substitui três métodos principais:
onCreateViewHolder()
:RecyclerView
chama esse método sempre que precisa criar um novoViewHolder
. O método cria e inicializa oViewHolder
e oView
associado, mas não preenche o conteúdo da visualização. OViewHolder
ainda não foi vinculado a dados específicos.onBindViewHolder()
:RecyclerView
chama esse método para associar umViewHolder
aos dados. O método busca os dados apropriados e usa esses dados para preencher o layout do fixador de visualização. Por exemplo, seRecyclerView
exibir uma lista de nomes, o método poderá encontrar o nome apropriado na lista e preencher a visualização do widgetTextView
.getItemCount()
:RecyclerView
chama esse método para receber o tamanho do conjunto de dados. Por exemplo: em um aplicativo de catálogo de endereços, esse pode ser o número total de endereços. A RecyclerView usa isso para determinar quando não há mais itens que podem ser exibidos.
Veja um exemplo típico de adaptador simples com um ViewHolder
aninhado que
exibe uma lista de dados. Nesse caso, o RecyclerView exibe uma lista simples
de elementos de texto. O adaptador recebe uma matriz de strings contendo o texto
para os elementos ViewHolder
.
Kotlin
class CustomAdapter(private val dataSet: Array<String>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() { /** * Provide a reference to the type of views that you are using * (custom ViewHolder) */ class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { val textView: TextView init { // Define click listener for the ViewHolder's View textView = view.findViewById(R.id.textView) } } // Create new views (invoked by the layout manager) override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder { // Create a new view, which defines the UI of the list item val view = LayoutInflater.from(viewGroup.context) .inflate(R.layout.text_row_item, viewGroup, false) return ViewHolder(view) } // Replace the contents of a view (invoked by the layout manager) override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) { // Get element from your dataset at this position and replace the // contents of the view with that element viewHolder.textView.text = dataSet[position] } // Return the size of your dataset (invoked by the layout manager) override fun getItemCount() = dataSet.size }
Java
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> { private String[] localDataSet; /** * Provide a reference to the type of views that you are using * (custom ViewHolder) */ public static class ViewHolder extends RecyclerView.ViewHolder { private final TextView textView; public ViewHolder(View view) { super(view); // Define click listener for the ViewHolder's View textView = (TextView) view.findViewById(R.id.textView); } public TextView getTextView() { return textView; } } /** * Initialize the dataset of the Adapter * * @param dataSet String[] containing the data to populate views to be used * by RecyclerView */ public CustomAdapter(String[] dataSet) { localDataSet = dataSet; } // Create new views (invoked by the layout manager) @Override public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { // Create a new view, which defines the UI of the list item View view = LayoutInflater.from(viewGroup.getContext()) .inflate(R.layout.text_row_item, viewGroup, false); return new ViewHolder(view); } // Replace the contents of a view (invoked by the layout manager) @Override public void onBindViewHolder(ViewHolder viewHolder, final int position) { // Get element from your dataset at this position and replace the // contents of the view with that element viewHolder.getTextView().setText(localDataSet[position]); } // Return the size of your dataset (invoked by the layout manager) @Override public int getItemCount() { return localDataSet.length; } }
O layout de cada item de visualização é definido em um arquivo de layout XML, como de costume.
Nesse caso, o app tem um arquivo text_row_item.xml
como este:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/list_item_height"
android:layout_marginLeft="@dimen/margin_medium"
android:layout_marginRight="@dimen/margin_medium"
android:gravity="center_vertical">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/element_text"/>
</FrameLayout>
Próximas etapas
O snippet de código abaixo mostra como usar a RecyclerView
.
Kotlin
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val dataset = arrayOf("January", "February", "March") val customAdapter = CustomAdapter(dataset) val recyclerView: RecyclerView = findViewById(R.id.recycler_view) recyclerView.layoutManager = LinearLayoutManager(this) recyclerView.adapter = customAdapter } }
Java
RecyclerView recyclerView = findViewById(R.id.recycler_view); recyclerView.layoutManager = new LinearLayoutManager(this) recyclerView.setAdapter(customAdapter);
A biblioteca também oferece muitas maneiras de personalizar a implementação. Para mais informações, consulte RecyclerView avançada personalização.
Outros recursos
Para saber mais sobre testes no Android, consulte os recursos a seguir.
Apps de amostra
App de amostra RecyclerView (Kotlin) (em inglês)
App de amostra RecyclerView (Java) (em inglês)
App de demonstração Sunflower (em inglês)