O Android GridLayoutManager é a implementação RecyclerView.LayoutManager
para dispor itens em uma grade. Neste tutorial, vamos criar uma aplicação que exibe CardViews dentro de um RecyclerView na forma de um GridLayout. Além disso, vamos implementar uma interface que torna o clique no item do RecyclerView semelhante a um ListView itemClickListener
.
Android GridLayoutManager
Implementamos um RecyclerView usando um LinearLayoutManager aqui. Agora vamos usar um GridLayoutManager
para dispor o RecyclerView como uma grade. A seguir está o construtor para um GridLayoutManager.
GridLayoutManager (Context context,
int spanCount,
int orientation,
boolean reverseLayout)
reverseLayout se definido como true, então os itens são dispostos do fim para o início. Para definir o tamanho da extensão para cada item, invocamos o método setSpanSizeLookup
no GridLayoutManager. Vamos implementar o RecyclerView usando um GridLayoutManager em um novo projeto do Android Studio.
Exemplo de Estrutura de Projeto GridLayoutManager do Android
O projeto consiste em uma única atividade:
MainActivity.java
, uma classe adaptadora: RecyclerViewAdapter.java
, uma classe DataModel.java
e uma classe GridLayoutManager personalizada AutoFitGridLayoutManager.java
. O layout xml da classe MainActivity.java é definido no arquivo activity_main.xml
como
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="https://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
Nota: Não esqueça de adicionar as seguintes dependências para widgets de Material Design e CardView
no arquivo build.gradle.
compile 'com.android.support:cardview-v7:25.1.1'
compile 'com.android.support:design:25.1.1'
A classe DataModel.java
é mostrada abaixo: package com.journaldev.recyclerviewgridlayoutmanager;
public class DataModel {
public String text;
public int drawable;
public String color;
public DataModel(String t, int d, String c )
{
text=t;
drawable=d;
color=c;
}
}
A classe DataModel irá armazenar o texto, ícone desenhável e cor de fundo de cada célula de item. A classe RecyclerViewAdapter.java é mostrada abaixo:
package com.journaldev.recyclerviewgridlayoutmanager;
import android.content.Context;
import android.graphics.Color;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.util.ArrayList;
public class RecyclerViewAdapter extends RecyclerView.Adapter {
ArrayList mValues;
Context mContext;
protected ItemListener mListener;
public RecyclerViewAdapter(Context context, ArrayList values, ItemListener itemListener) {
mValues = values;
mContext = context;
mListener=itemListener;
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView textView;
public ImageView imageView;
public RelativeLayout relativeLayout;
DataModel item;
public ViewHolder(View v) {
super(v);
v.setOnClickListener(this);
textView = (TextView) v.findViewById(R.id.textView);
imageView = (ImageView) v.findViewById(R.id.imageView);
relativeLayout = (RelativeLayout) v.findViewById(R.id.relativeLayout);
}
public void setData(DataModel item) {
this.item = item;
textView.setText(item.text);
imageView.setImageResource(item.drawable);
relativeLayout.setBackgroundColor(Color.parseColor(item.color));
}
@Override
public void onClick(View view) {
if (mListener != null) {
mListener.onItemClick(item);
}
}
}
@Override
public RecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.recycler_view_item, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder Vholder, int position) {
Vholder.setData(mValues.get(position));
}
@Override
public int getItemCount() {
return mValues.size();
}
public interface ItemListener {
void onItemClick(DataModel item);
}
}
No código acima, definimos uma interface ItemListener que será implementada na classe MainActivity.java. O layout xml para cada item RecyclerView é mostrado abaixo. recycler_view_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:card_view="https://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="150dp"
card_view:cardCornerRadius="0dp"
card_view:cardElevation="@dimen/margin10"
card_view:cardMaxElevation="@dimen/margin10"
card_view:contentPadding="@dimen/margin10">
<RelativeLayout
android:id="@+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_gravity="center">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:tint="@android:color/white"
android:padding="5dp" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:textColor="@android:color/white"
android:layout_below="@+id/imageView" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
A classe AutoFitGridLayoutManager.java é mostrada abaixo:
package com.journaldev.recyclerviewgridlayoutmanager;
import android.content.Context;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
public class AutoFitGridLayoutManager extends GridLayoutManager {
private int columnWidth;
private boolean columnWidthChanged = true;
public AutoFitGridLayoutManager(Context context, int columnWidth) {
super(context, 1);
setColumnWidth(columnWidth);
}
public void setColumnWidth(int newColumnWidth) {
if (newColumnWidth > 0 && newColumnWidth != columnWidth) {
columnWidth = newColumnWidth;
columnWidthChanged = true;
}
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
if (columnWidthChanged && columnWidth > 0) {
int totalSpace;
if (getOrientation() == VERTICAL) {
totalSpace = getWidth() - getPaddingRight() - getPaddingLeft();
} else {
totalSpace = getHeight() - getPaddingTop() - getPaddingBottom();
}
int spanCount = Math.max(1, totalSpace / columnWidth);
setSpanCount(spanCount);
columnWidthChanged = false;
}
super.onLayoutChildren(recycler, state);
}
}
A contagem de span é calculada dinamicamente com base na orientação, largura e altura disponíveis. A classe MainActivity.java
está apresentada abaixo:
package com.journaldev.recyclerviewgridlayoutmanager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity implements RecyclerViewAdapter.ItemListener {
RecyclerView recyclerView;
ArrayList arrayList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
arrayList = new ArrayList();
arrayList.add(new DataModel("Item 1", R.drawable.battle, "#09A9FF"));
arrayList.add(new DataModel("Item 2", R.drawable.beer, "#3E51B1"));
arrayList.add(new DataModel("Item 3", R.drawable.ferrari, "#673BB7"));
arrayList.add(new DataModel("Item 4", R.drawable.jetpack_joyride, "#4BAA50"));
arrayList.add(new DataModel("Item 5", R.drawable.three_d, "#F94336"));
arrayList.add(new DataModel("Item 6", R.drawable.terraria, "#0A9B88"));
RecyclerViewAdapter adapter = new RecyclerViewAdapter(this, arrayList, this);
recyclerView.setAdapter(adapter);
/**
AutoFitGridLayoutManager that auto fits the cells by the column width defined.
**/
/*AutoFitGridLayoutManager layoutManager = new AutoFitGridLayoutManager(this, 500);
recyclerView.setLayoutManager(layoutManager);*/
/**
Simple GridLayoutManager that spans two columns
**/
GridLayoutManager manager = new GridLayoutManager(this, 2, GridLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(manager);
}
@Override
public void onItemClick(DataModel item) {
Toast.makeText(getApplicationContext(), item.text + " is clicked", Toast.LENGTH_SHORT).show();
}
}
- A classe acima implementa a interface
RecyclerViewAdapter.ItemListener
e sobrescreve o métodoonItemClick
definido na classe do adaptador. Ao fazer isso, implementamos o ouvinte de clique do RecyclerView dentro de nossa Activity, em vez da classe do adaptador (semelhante ao padrão onItemClickListener definido para um ListView) - A DataModel class holds the details for each RecyclerView item
- O LayoutManager do RecyclerView pode ser definido tanto instanciando a classe AutoFitGridLayoutManager com a largura da coluna definida como 500, quanto invocando o objeto da classe GridLayoutManager e configurando o número de colunas como 2
Vamos ver a saída da aplicação com o código padrão do GridLayoutManager. Como você pode ver, cada linha possui dois itens que abrangem a largura da coluna em ambas as orientações. Agora, comente o código para o GridLayoutManager simples e execute o código para AutoFitGridLayoutManager
AutoFitGridLayoutManager layoutManager = new AutoFitGridLayoutManager(this, 500);
recyclerView.setLayoutManager(layoutManager);
A saída da aplicação em ação é dada abaixo. Como você pode ver na saída acima, quando a orientação muda para paisagem, cada linha tem três itens, dimensionando dinamicamente os itens para se ajustarem automaticamente à largura da coluna. Isso encerra este tutorial. Você pode baixar o projeto final do Android GridLayoutManager a partir do link abaixo.
Source:
https://www.digitalocean.com/community/tutorials/android-gridlayoutmanager-example