Ejemplo simple de grid en Android usando RecyclerView con GridLayoutManager (como el antiguo GridView)

Sé que RecyclerView ha reemplazado la funcionalidad de los antiguos ListView y GridView. Estoy buscando un ejemplo muy básico que muestre una configuración mínima de la cuadrícula utilizando RecyclerView. No estoy buscando largas explicaciones de estilo tutorial, sólo un ejemplo mínimo. Imagino que la rejilla más simple que imita el antiguo GridView consistiría en las siguientes características:

  • múltiples celdas por fila
  • una sola vista en cada celda
  • responde a eventos de clic
Solución

Respuesta corta

Para aquellos que ya están familiarizados con la configuración de un RecyclerView para hacer una lista, la buena noticia es que hacer una cuadrícula es en gran medida lo mismo. Sólo tienes que utilizar un GridLayoutManager en lugar de un LinearLayoutManager cuando configures el RecyclerView.

recyclerView.setLayoutManager(new GridLayoutManager(this, numberOfColumns));

Si necesitas más ayuda que eso, entonces mira el siguiente ejemplo.

Ejemplo completo

El siguiente es un ejemplo mínimo que se verá como la imagen de abajo.

[]

Comience con una actividad vacía. Realizará las siguientes tareas para añadir la rejilla RecyclerView. Todo lo que necesitas hacer es copiar y pegar el código en cada sección. Más tarde puedes personalizarlo para que se ajuste a tus necesidades.

  • Añadir dependencias a gradle
  • Añadir los archivos de diseño xml para la actividad y para la celda de la rejilla
  • Hacer el adaptador del RecyclerView
  • Inicialice el RecyclerView en su actividad

Actualizar las dependencias de Gradle

Asegúrate de que las siguientes dependencias están en el archivo gradle.build de tu aplicación:

compile 'com.android.support:appcompat-v7:27.1.1'
compile 'com.android.support:recyclerview-v7:27.1.1'

Puedes actualizar los números de versión a la que sea la más actual.

Crear el diseño de la actividad

Añade el RecyclerView a tu layout xml.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>




Crear el diseño de las celdas de la rejilla

Cada celda de nuestra rejilla RecyclerView sólo va a tener un único TextView. Crear un nuevo archivo de recursos de diseño.

recyclerview_item.xml

<?xml version="1.0" encoding="utf-8"?>




Crear el adaptador

El RecyclerView necesita un adaptador para rellenar las vistas de cada celda con sus datos. Crea un nuevo archivo java.

MyRecyclerViewAdapter.java

public class MyRecyclerViewAdapter extends RecyclerView.Adapter {

    private String[] mData;
    private LayoutInflater mInflater;
    private ItemClickListener mClickListener;

    // data is passed into the constructor
    MyRecyclerViewAdapter(Context context, String[] data) {
        this.mInflater = LayoutInflater.from(context);
        this.mData = data;
    }

    // inflates the cell layout from xml when needed
    @Override
    @NonNull 
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = mInflater.inflate(R.layout.recyclerview_item, parent, false);
        return new ViewHolder(view);
    }

    // binds the data to the TextView in each cell
    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        holder.myTextView.setText(mData[position]);
    }

    // total number of cells
    @Override
    public int getItemCount() {
        return mData.length;
    }

    // stores and recycles views as they are scrolled off screen
    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        TextView myTextView;

        ViewHolder(View itemView) {
            super(itemView);
            myTextView = itemView.findViewById(R.id.info_text);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
        }
    }

    // convenience method for getting data at click position
    String getItem(int id) {
        return mData[id];
    }

    // allows clicks events to be caught
    void setClickListener(ItemClickListener itemClickListener) {
        this.mClickListener = itemClickListener;
    }

    // parent activity will implement this method to respond to click events
    public interface ItemClickListener {
        void onItemClick(View view, int position);
    }
}

Notas

  • Aunque no es estrictamente necesario, he incluido la funcionalidad para escuchar los eventos de clic en las celdas. Esto estaba disponible en el antiguo GridView y es una necesidad común. Puedes eliminar este código si no lo necesitas.

Inicializar RecyclerView en la actividad

Agregue el siguiente código a su actividad principal.

MainActivity.java

public class MainActivity extends AppCompatActivity implements MyRecyclerViewAdapter.ItemClickListener {

    MyRecyclerViewAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // data to populate the RecyclerView with
        String[] data = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48"};

        // set up the RecyclerView
        RecyclerView recyclerView = findViewById(R.id.rvNumbers);
        int numberOfColumns = 6;
        recyclerView.setLayoutManager(new GridLayoutManager(this, numberOfColumns));
        adapter = new MyRecyclerViewAdapter(this, data);
        adapter.setClickListener(this);
        recyclerView.setAdapter(adapter);
    }

    @Override
    public void onItemClick(View view, int position) {
        Log.i("TAG", "You clicked number " + adapter.getItem(position) + ", which is at cell position " + position);
    }
}

Notas

  • Observa que la actividad implementa el ItemClickListener que hemos definido en nuestro adaptador. Esto nos permite manejar los eventos de clic de las celdas en onItemClick.

Terminado

Eso'es todo. Ahora deberías poder ejecutar tu proyecto y obtener algo similar a la imagen de la parte superior.

Continuando

Esquinas redondeadas

Ajuste automático de las columnas

Estudio adicional

Comentarios (20)

Aunque me gusta y aprecio la respuesta de Suragch's, me gustaría dejar una nota porque he encontrado que codificar el Adapter (MyRecyclerViewAdapter) para definir y exponer el método Listener onItemClick no es la mejor manera de hacerlo, debido a que no se utiliza la encapsulación de clases correctamente. Así que mi sugerencia es dejar que el Adaptador se encargue únicamente de las operaciones de escucha (¡ese es su propósito!) y separarlas de la actividad que utiliza el Adaptador (MainActivity). Así es como yo establecería la clase Adapter:

MyRecyclerViewAdapter.java

public class MyRecyclerViewAdapter extends RecyclerView.Adapter {

    private String[] mData = new String[0];
    private LayoutInflater mInflater;

    // Data is passed into the constructor
    public MyRecyclerViewAdapter(Context context, String[] data) {
        this.mInflater = LayoutInflater.from(context);
        this.mData = data;
    }

    // Inflates the cell layout from xml when needed
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = mInflater.inflate(R.layout.recyclerview_item, parent, false);
        ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }

    // Binds the data to the textview in each cell
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        String animal = mData[position];
        holder.myTextView.setText(animal);
    }

    // Total number of cells
    @Override
    public int getItemCount() {
        return mData.length;
    }

    // Stores and recycles views as they are scrolled off screen
    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public TextView myTextView;

        public ViewHolder(View itemView) {
            super(itemView);
            myTextView = (TextView) itemView.findViewById(R.id.info_text);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            onItemClick(view, getAdapterPosition());
        }
    }

    // Convenience method for getting data at click position
    public String getItem(int id) {
        return mData[id];
    }

    // Method that executes your code for the action received
    public void onItemClick(View view, int position) {
        Log.i("TAG", "You clicked number " + getItem(position).toString() + ", which is at cell position " + position);
    }
}

Por favor, tenga en cuenta el método onItemClick ahora definido en MyRecyclerViewAdapter que es el lugar donde querrá codificar sus tareas para el evento/acción recibido.

Sólo hay que hacer un pequeño cambio para completar esta transformación: la Activity ya no necesita implementar MyRecyclerViewAdapter.ItemClickListener, porque ahora eso lo hace completamente el Adapter. Esta sería entonces la modificación final:

MainActivity.java

public class MainActivity extends AppCompatActivity {

    MyRecyclerViewAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // data to populate the RecyclerView with
        String[] data = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48"};

        // set up the RecyclerView
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rvNumbers);
        int numberOfColumns = 6;
        recyclerView.setLayoutManager(new GridLayoutManager(this, numberOfColumns));
        adapter = new MyRecyclerViewAdapter(this, data);
        adapter.setClickListener(this);
        recyclerView.setAdapter(adapter);
    }
}
Comentarios (3)

Usted tiene que establecer su recyclerview layoutmanager al modo Gridlayout, para hacer esto sólo tiene que cambiar su código cuando usted quiere establecer su RecyclerView LayoutManager:

Nota: reemplazar su cuenta de columnas que desea con ###HELP###

   recyclerView.setLayoutManager(new GridLayoutManager(getActivity(),##HELP###));
Comentarios (0)