Criar listas dinâmicas com o 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. O RecyclerView melhora o desempenho e a capacidade de resposta do app, além de reduzir o consumo de energia.
Classes principais
Várias classes trabalham juntas para criar sua lista dinâmica.
RecyclerView
é oViewGroup
que contém as visualizações correspondentes aos seus dados. Ela é uma visualização em si, então adicione aRecyclerView
ao layout da mesma forma que você adicionaria qualquer outro elemento da IU.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 as vincula aos dados delas, 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 amostra RecyclerView (Kotlin) ou no app de amostra RecyclerView (Java) (links em inglês).
Etapas para implementar o RecyclerView
Se você quiser usar o RecyclerView, é necessário realizar algumas ações. Elas serão explicadas em detalhes nas seções a seguir.
Decida como a lista ou a grade vai ficar. Normalmente, é possível usar um dos gerenciadores de layout padrão da biblioteca RecyclerView.
Crie 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 criar o layout dos itens individuais. Você vai precisar desse layout 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 seu layout, é necessário implementar o Adapter
e o
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 objetos
ViewHolder
conforme necessário e também define 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, se aRecyclerView
mostrar uma lista de nomes, o método poderá encontrar o nome apropriado na lista e preencher o widgetTextView
do detentor de visualização.getItemCount()
:RecyclerView
chama esse método para conferir o tamanho do conjunto de dados. Por exemplo, em um app de lista de endereços, pode ser o número total de endereços. O RecyclerView usa essa função para determinar quando não há mais itens a serem 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 que contém o texto
dos 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 o 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 Personalização avançada do RecyclerView.
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)