web-dev-qa-db-fra.com

Exemple de grille simple Android utilisant RecyclerView avec GridLayoutManager (comme l'ancien GridView)

Je sais que RecyclerView a remplacé les fonctionnalités de l'ancien ListView et GridView. Je cherche un exemple très basique montrant une configuration de grille minimale utilisant RecyclerView. Je ne cherche pas de longues explications de style de tutoriel, juste un exemple minimal. J'imagine que la grille la plus simple qui imite l'ancien GridView aurait les caractéristiques suivantes:

  • plusieurs cellules par rangée
  • vue unique dans chaque cellule
  • répond aux événements de clic
166
Suragch

Réponse courte

Pour ceux qui sont déjà familiarisés avec mettre en place une RecyclerView pour faire une liste , la bonne nouvelle est que faire une grille est en grande partie identique. Vous utilisez simplement un GridLayoutManager au lieu d'un LinearLayoutManager lorsque vous activez le RecyclerView.

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

Si vous avez besoin de plus d’aide, consultez l’exemple suivant.

Exemple complet

Ce qui suit est un exemple minimal qui ressemblera à l'image ci-dessous.

enter image description here

Commencez avec une activité vide. Vous allez effectuer les tâches suivantes pour ajouter la grille RecyclerView. Tout ce que vous avez à faire est de copier et coller le code dans chaque section. Plus tard, vous pourrez le personnaliser pour répondre à vos besoins.

  • Ajouter des dépendances à graver
  • Ajouter les fichiers de présentation XML pour l'activité et pour la cellule de la grille
  • Fabriquer l'adaptateur RecyclerView
  • Initialiser le RecyclerView dans votre activité

Mettre à jour les dépendances Gradle

Assurez-vous que les dépendances suivantes sont dans votre fichier app gradle.build:

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

Vous pouvez mettre à jour les numéros de version vers tout ce qui est le plus récent .

Créer une mise en page d'activité

Ajoutez le RecyclerView à votre mise en page XML.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <Android.support.v7.widget.RecyclerView
        Android:id="@+id/rvNumbers"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"/>

</RelativeLayout>

Créer une disposition de cellule de grille

Chaque cellule de notre grille RecyclerView n'aura qu'un seul TextView. Créez un nouveau fichier de ressources de présentation.

recyclerview_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:orientation="horizontal"
    Android:padding="5dp"
    Android:layout_width="50dp"
    Android:layout_height="50dp">

        <TextView
            Android:id="@+id/info_text"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:gravity="center"
            Android:background="@color/colorAccent"/>

</LinearLayout>

Créer l'adaptateur

La RecyclerView nécessite un adaptateur pour renseigner les vues de chaque cellule avec vos données. Créez un nouveau fichier Java.

MyRecyclerViewAdapter.Java

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> {

    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);
    }
}

Remarques

  • Bien que cela ne soit pas strictement nécessaire, j'ai inclus la fonctionnalité permettant d'écouter les événements de clic sur les cellules. C'était disponible dans l'ancien GridView et c'est un besoin commun. Vous pouvez supprimer ce code si vous n'en avez pas besoin.

Initialiser RecyclerView en activité

Ajoutez le code suivant à votre activité principale.

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);
    }
}

Remarques

  • Notez que l'activité implémente la ItemClickListener que nous avons définie dans notre adaptateur. Cela nous permet de gérer les événements de clic de cellule dans onItemClick.

Fini

C'est ça. Vous devriez être capable de lancer votre projet maintenant et d’obtenir quelque chose de similaire à l’image en haut.

Continuer

Coins arrondis

Colonnes à ajustement automatique

Une étude plus approfondie

420
Suragch

Bien que j'aime bien et que j'apprécie la réponse de Suragch , je voudrais laisser une note, car j'ai trouvé que coder le Adaptateur (MyRecyclerViewAdapter) pour définir et exposer la méthode Listener onItemClick n'est pas la meilleure façon de le faire, car en utilisant correctement l’encapsulation de classe. Ma suggestion est donc de laisser l'adaptateur gérer uniquement les opérations d'écoute (c'est son objectif!) Et de séparer celles de l'activité qui utilise le Adaptateur (MainActivity). Voici comment je définirais la classe Adapter:

MyRecyclerViewAdapter.Java

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> {

    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);
    }
}

Veuillez noter que la méthode onItemClick maintenant définie dans MyRecyclerViewAdapter est l'endroit où vous souhaitez coder vos tâches pour l'événement/l'action reçu.

Il ne reste qu'un petit changement à faire pour mener à bien cette transformation: l'activité n'a plus besoin d'implémenter MyRecyclerViewAdapter.ItemClickListener, car Maintenant, cela se fait complètement avec l'adaptateur . Ce serait alors la modification finale:

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);
    }
}
6
jonypera

source de référence moyenne

repo GitHub

Ajouter une dépendance RecyclerView dans build.gradle

compile 'com.Android.support:recyclerview-v7:25.1.1'

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:id="@+id/activity_main"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    >

    <!--TODO(2): RecyclerView inside FrameLayout-->

    <Android.support.v7.widget.RecyclerView
        Android:id="@+id/rvStudents"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:scrollbars="none"
        >
    </Android.support.v7.widget.RecyclerView>

    <!--TODO(3): Create one layout resource with item_student.xml name-->

</FrameLayout>

item_student.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:orientation="vertical" Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:background="#d2d2d2"
    Android:id="@+id/llItemStudents"
    Android:layout_margin="8dp"
    >

    <!--TODO(4): Remember to change the height of LinearLayout to wrap_content and also add its ID-->

    <!--TODO(5): Add two TextView which will display student name and mobile number respectively-->

    <TextView
        Android:id="@+id/tvStudentName"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_margin="8dp"
        Android:padding="8dp"
        Android:textSize="25sp"
        Android:textStyle="bold"
        Android:textColor="@color/colorPrimary"
        />

    <TextView
        Android:id="@+id/tvMobileNumber"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_margin="8dp"
        Android:padding="8dp"
        Android:textSize="22sp"
        Android:textStyle="bold"
        Android:textColor="@color/colorAccent"
        />

</LinearLayout>

MainActivity.Java

import Android.support.v7.app.AppCompatActivity;
import Android.os.Bundle;
import Android.support.v7.widget.GridLayoutManager;
import Android.support.v7.widget.LinearLayoutManager;
import Android.support.v7.widget.RecyclerView;
import Android.support.v7.widget.StaggeredGridLayoutManager;
import Android.text.Layout;

import Java.util.ArrayList;

/*
 * Demo Code of Recycler View
 * Created on: 19th Feb, 2017
 * Author Name: Rajat Talesra
 * Company Name: WiseL
 * This code is for Android Monk Campus Program.
 */

/*
 * Recycler View is mainly used to show dynamic list of data.
 * Many applications including Whatsapp, Facebook, Gmail, etc. used RecyclerView
 *
 * RecyclerView mainly uses two main components LayoutManager and Adapter
 *
 * LayoutManger: Helps to arrange data in LinearLayout or GridLayout
 *
 * Adapter: Helps to connect our recycler view with the custom layout and display data on screen
 *
 * In this demo we will display students list with their names and mobile numbers.
 */

public class MainActivity extends AppCompatActivity {

    //TODO(6): Create arrayList for student names and ids.

    ArrayList<String> namesArrayList = new ArrayList<>();
    ArrayList<String> mobileArrayList = new ArrayList<>();

    //TODO(7): Declare below mentioned components.

    RecyclerView rvStudentsList;
    RecyclerView.LayoutManager rvLayoutManager;

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

        //TODO(10): Add data to arrayList
        namesArrayList.add("Student 1");
        namesArrayList.add("Student 2");
        namesArrayList.add("Student 3");
        namesArrayList.add("Student 4");
        namesArrayList.add("Student 5");
        namesArrayList.add("Student 6");
        namesArrayList.add("Student 7");
        namesArrayList.add("Student 8");
        namesArrayList.add("Student 9");
        namesArrayList.add("Student 10");

        mobileArrayList.add("8766986401");
        mobileArrayList.add("8766986402");
        mobileArrayList.add("8766986403");
        mobileArrayList.add("8766986404");
        mobileArrayList.add("8766986405");
        mobileArrayList.add("8766986406");
        mobileArrayList.add("8766986407");
        mobileArrayList.add("8766986408");
        mobileArrayList.add("8766986409");
        mobileArrayList.add("8766986410");

        //TODO(9): Connect UI elements with Java objects.
        rvStudentsList = (RecyclerView) findViewById(R.id.rvStudents);


        //User this to display items vertically
        //rvLayoutManager = new LinearLayoutManager(this);

        //User this to display items in Grid Layout with 2 columns
        rvLayoutManager = new GridLayoutManager(this,2);

        //TODO(10): Attach layoutManager to recycler view
        rvStudentsList.setLayoutManager(rvLayoutManager);

        /*
         * Now we need to create one adapter, so that we can display data row wise
         * For this we will create our custom adapter, i.e. StudentAdapter.Java
         */

        //TODO(11): Create new Java class StudentAdapter.Java

        //TODO(16): Pass data to our custom adapter
        StudentAdapter studentAdapter = new StudentAdapter(this,namesArrayList,mobileArrayList);

        //TODO(17): Attach studentAdapter to recycler view

        rvStudentsList.setAdapter(studentAdapter);

        //TODO(18): Run your app.

    }
}

StudentAdapter.Java

import Android.content.Context;
import Android.support.v7.widget.RecyclerView;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.LinearLayout;
import Android.widget.TextView;
import Android.widget.Toast;

import Java.util.ArrayList;

//TODO(12): StudentAdapter extends RecyclerView Adapter with ViewHolder class


public class StudentAdapter extends RecyclerView.Adapter<StudentAdapter.ViewHolder> {

    //TODO(13): Create two empty arrayList and one context variable;

    Context mainActivityContext;
    ArrayList<String> namesArrayList = new ArrayList<>();
    ArrayList<String> mobileArrayList = new ArrayList<>();

    //TODO(14): Create one constructor with three parameters which will passed from MainActivity class

    public StudentAdapter(Context mainActivityContext, ArrayList<String> namesArrayList, ArrayList<String> mobileArrayList) {
        this.mainActivityContext = mainActivityContext;
        this.namesArrayList = namesArrayList;
        this.mobileArrayList = mobileArrayList;
    }

    //TODO(15): Complete each method as mentioned below


    @Override
    public StudentAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //Used to connect our custom UI to our recycler view

        View v = LayoutInflater
                .from(parent.getContext())
                .inflate(R.layout.item_student, parent, false);

        return new ViewHolder(v);
    }

    @Override
    public void onBindViewHolder(StudentAdapter.ViewHolder holder, int position) {
        //Used to set data in each row of recycler view

        String currentName = namesArrayList.get(position);
        String currentMobileNumber = mobileArrayList.get(position);

        holder.tvName.setText(currentName);
        holder.tvMobileNumber.setText(currentMobileNumber);

    }

    @Override
    public int getItemCount() {
        //Returns total number of rows inside recycler view

        return namesArrayList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        //Used to work with the elements of our custom UI.

        LinearLayout llItemStudents;

        TextView tvName;
        TextView tvMobileNumber;

        public ViewHolder(View itemView) {
            super(itemView);

            tvName = (TextView) itemView.findViewById(R.id.tvStudentName);
            tvMobileNumber = (TextView) itemView.findViewById(R.id.tvMobileNumber);

            llItemStudents = (LinearLayout) itemView.findViewById(R.id.llItemStudents);

            llItemStudents.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(mainActivityContext,
                            "You clicked item number: "+ getAdapterPosition(),
                            Toast.LENGTH_SHORT).show();
                }
            });

        }
    }
}

Aussi s'il vous plaît visitez doc officiel

0
yoAlex5