Dans ce tutoriel, nous examinerons la création et l'utilisation d'une vue de recyclage personnalisée avec des cases à cocher ou des boutons radio et comment gérer leurs états.

Concepts que vous allez apprendre

Ce tutoriel, via des exemples, a pour but de vous aider à apprendre ce qui suit :

  1. Comment créer une vue recyclée avec des cases à cocher ou des boutons radios et comment gérer leurs états de manière appropriée.
  2. Comment rendre les données d'une base de données mysql, y compris les données booléennes, dans une vue recyclée avec des cases à cocher.
  3. Comment rechercher/filtrer une vue recyclée avec des cases à cocher tout en maintenant leurs états coché/décoché.

Démos

Voici quelques-unes des démos qui seront créées :

Démo CheckBox


Kotlin RecyclerView CheckBox Example

Démo RadioButton


Android RecyclerView RadioButton Example

Exemple 1 : Android RecyclerView CheckBoxes - Maintenir les états vérifiés

Ceci est un tutoriel sur les checkboxes Android RecyclerView. Nous voulons voir comment d'abord rendre les cases à cocher, les images et le texte dans un recyclerview personnalisé avec cardviews. Puis récupérer les cardviews sélectionnées ou cochées et les afficher dans un message Toast. Nous travaillons avec plusieurs cases à cocher afin de pouvoir sélectionner plusieurs éléments ou un seul dans notre RecyclerView.

Cela nous apprendra comment conserver correctement les états cochés de nos cases à cocher dans notre Recyclerview malgré le recyclage de nos cardviews avec cases à cocher.

L'utilisateur peut ensuite cliquer sur un bouton d'action flottant pour obtenir les éléments sélectionnés et les afficher dans un message Toast.

Nous construisons une communauté YouTube dynamique

Voici ce tutoriel en format vidéo.

Étape 1 : Dépendances

Nous n'avons pas besoin de dépendance particulière pour ce projet. Tout ce que nous utilisons sont les dépendances standard androidx comme recyclerview et cardview.

Step 2 : Création de la mise en page de l'activité principale

activity_main.xml

Ce sera notre activité principale et nous l'écrivons en XML. Le XML est un langage de balisage qui n'est pas seulement utilisé pour créer des interfaces utilisateur mais aussi pour exchner des données, dans ce cas nous l'utilisons pour créer notre interface utilisateur Android.

Ce layout sera gonflé dans notre activité principale. A la racine, nous avons un RelativeLayout.

Nous avons un TextView qui est notre headerTextView pour afficher le titre de notre application android.

Ensuite, nous avons un RecyclerView qui, dans ce cas, est notre adapterview. Ce RecyclerView rendra les images, le texte et les cases à cocher.

En dessous de la RecyclerView, nous avons un FloatingActionButton. Lorsque les utilisateurs cliqueront sur ce bouton FAB, nous afficherons les éléments qui ont été sélectionnés dans la vue de recyclage. Rappelez-vous que notre recyclerview sera composé de cardviews qui ont des images, du texte et des cases à cocher.

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

    android_layout_width="match_parent"
    android_layout_height="match_parent"
    tools_context="info.camposha.checkablerecyclerviews.MainActivity">

    <TextView
        android_id="@+id/headerTextView"
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_text="Spiritual Teachers"
        android_textAlignment="center"
        android_textAppearance="@style/TextAppearance.AppCompat.Large"
        android_textColor="@color/colorAccent" />

    <androidx.recyclerview.widget.RecyclerView
        android_id="@+id/myRecycler"
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_layout_alignParentLeft="true"
        android_layout_alignParentStart="true"
        android_layout_below="@+id/headerTextView"
        android_layout_marginTop="30dp" />

    <android.support.design.widget.FloatingActionButton
        android_id="@+id/fab"
        android_layout_width="wrap_content"
        android_layout_height="wrap_content"
        android_layout_alignParentBottom="true"
        android_layout_alignParentEnd="true"
        android_layout_alignParentRight="true"
        android_layout_gravity="bottom|end"
        android_src="@android:drawable/ic_dialog_email" />

</RelativeLayout>

Étape 3 : Créer un élément de RecyclerView

model.xml

Cette mise en page modélisera une seule cardview à rendre parmi les autres cartes de notre recyclerview.

Ce layout va modéliser toutes ces cardviews. A la racine, nous avons le CardView comme élément. CardView réside dans l'espace de noms android.support.v7.widget.

J'ai défini l'élévation de la carte à 5dp et son rayon de courbure à 10dp.

À l'intérieur, j'ai un RelativeLayout pour organiser mes widgets les uns par rapport aux autres.

Tout d'abord, nous avons l'ImageView pour rendre notre image. Puis les TextViews pour rendre nos textes.

À l'extrême droite de notre CardView, nous avons une CheckBox qui contient la propriété de sélection de chaque CardView. Les CheckBox peuvent être cochées ou non cochées.

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    android_orientation="horizontal" android_layout_width="match_parent"

    android_layout_margin="5dp"
    card_view_cardCornerRadius="10dp"
    card_view_cardElevation="5dp"
    android_layout_height="match_parent">

    <RelativeLayout
        android_layout_width="match_parent"
        android_layout_height="match_parent">
        <ImageView
            android_layout_width="150dp"
            android_layout_height="150dp"
            android_id="@+id/teacherImageView"
            android_padding="5dp"
            android_src="@drawable/cle" />

        <TextView
            android_layout_width="wrap_content"
            android_layout_height="wrap_content"
            android_textAppearance="?android:attr/textAppearanceLarge"
            android_text="Teacher Name"
            android_id="@+id/nameTextView"
            android_padding="5dp"
            android_textColor="@color/colorAccent"
            android_layout_alignParentTop="true"
            android_layout_toRightOf="@+id/teacherImageView" />

        <TextView
            android_layout_width="wrap_content"
            android_layout_height="wrap_content"
            android_textAppearance="?android:attr/textAppearanceMedium"
            android_text="Teacher Description..."
            android_id="@+id/descritionTextView"
            android_padding="5dp"
            android_layout_alignBottom="@+id/teacherImageView"
            android_layout_toRightOf="@+id/teacherImageView" />

        <CheckBox
            android_layout_width="wrap_content"
            android_layout_height="wrap_content"
            android_id="@+id/myCheckBox"
            android_layout_alignParentRight="true"
            />

    </RelativeLayout>
</androidx.cardview.widget.CardView>

Étape 4 : MainActivity.java

Spécifier le paquet et ajouter les importations

Notre classe java résidera dans un package, donc nous en spécifions un et ajoutons les imports appropriés.

Ceux-ci incluent notre RecyclerView du paquet android.support.v7.widget et CheckBox du paquet android.widget.

package info.camposha.checkablerecyclerviews;

import android.content.Context;
import android.support.design.widget.FloatingActionButton;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
Créer une activité

Une activité est un composant android qui représente une interface utilisateur.

Pour transformer notre classe ordinaire en activité, nous allons la faire dériver de AppCompatActivity :

public class MainActivity extends AppCompatActivity {..}
Créer notre POJO

Nous allons ensuite créer une classe POJO, Plain OLd Java Object. Celle-ci représentera un seul objet Teacher.

Chaque Enseignant aura plusieurs propriétés. Chaque objet sera rendu dans sa propre CardView dans notre RecyclerView.

    public class SpiritualTeacher {
        //our properties.
    }

L'une de ces propriétés sera la propriété isSelected, une valeur booléenne qui tiendra pour nous l'état coché de notre CardView.

Créer notre View Holder

Nous allons créer notre classe ViewHolder de RecyclerView en dérivant de la classe RecyclerView.ViewHolder.

La classe implémentera également l'interface View.OnClickListener. Cela nous permettra de capturer les événements de clic de notre chaque CardView.

    static class MyHolder extends RecyclerView.ViewHolder implements View.OnClickListener{...}
Créer l'adaptateur RecyclerView

Ensuite, nous venons créer notre classe RecyclerView.Adapter, la classe qui sera notre classe d'adaptateur.

    static class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder> {..}

En tant que classe d'adaptateur, cette classe a deux rôles principaux :

  1. Gonfler notre modèle personnalisé de mise en page dans un objet de vue.
  2. Lier un ensemble de données à nos vues gonflées.

Les données à lier proviendront d'un tableau personnalisé, dans ce cas un tableau de SpiritualTeachers :

        public MyAdapter(Context c, SpiritualTeacher[] teachers) {
            this.c = c;
            this.teachers = teachers;
        }

Cette classe maintiendra également un arraylist qui contiendra nos éléments vérifiés.

        ArrayList<SpiritualTeacher> checkedTeachers=new ArrayList<>();

Les utilisateurs vont vérifier les éléments de recyclerview et nous maintenons ces éléments vérifiés dans ce arraylist. Ensuite, plus tard, nous pouvons afficher ces éléments vérifiés dans un message Toast.

Gonfler la mise en page dans la vue

Cette opération aura lieu dans notre adaptateur RecyclerView, comme nous l'avons convenu. Nous avons besoin d'une classe LayoutInflater pour faire cela.

        @Override
        public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.model,null);
            MyHolder holder=new MyHolder(v);
            return holder;
        }

Ensuite, comme vous pouvez le voir, nous avons passé l'objet inflate view dans le constructeur de notre RecyclerView ViewHolder.
Puis nous avons retourné l'instance View Holder.

Lier des données

Nous lions les données dans la méthode onBindViewHolder :

        @Override
        public void onBindViewHolder(MyHolder holder, int position) {
            final SpiritualTeacher teacher=teachers[position];
            holder.nameTxt.setText(teacher.getName());
            holder.posTxt.setText(teacher.getQuote());
            holder.myCheckBox.setChecked(teacher.isSelected());
            holder.img.setImageResource(teacher.getImage());
            ...
        }

Tout d'abord, nous avons reçu la position de l'élément dans notre recyclerview et l'avons utilisé pour obtenir le professeur actuel de notre tableau.

Ensuite, nous avons défini les widgets TextView, imageView et CheckBox avec les valeurs de cet objet.

Maintenir les éléments cochés et non cochés

Nous écoutons ensuite les événements de clics de notre CardView. Il est évident que cliquer sur la case à cocher changera l'état de cette case.

Nous vérifions ces changements. Si la case à cocher est cochée, nous ajoutons l'élément dans notre liste de tableaux.

Si elle est décochée, nous retirons l'élément de la liste de tableaux.

            holder.setItemClickListener(new MyHolder.ItemClickListener() {
                @Override
                public void onItemClick(View v, int pos) {
                    CheckBox myCheckBox= (CheckBox) v;
                    SpiritualTeacher currentTeacher=teachers[pos];

                    if(myCheckBox.isChecked()) {
                        currentTeacher.setSelected(true);
                        checkedTeachers.add(currentTeacher);
                    }
                    else if(!myCheckBox.isChecked()) {
                        currentTeacher.setSelected(false);
                        checkedTeachers.remove(currentTeacher);
                    }
                }
            });

Regardons le code source complet.

Code complet

Voici le code complet de MainActivity.

package info.camposha.checkablerecyclerviews;

import android.content.Context;
import android.support.design.widget.FloatingActionButton;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    public class SpiritualTeacher {
        private String name,quote;
        private int image;
        private boolean isSelected;

        public SpiritualTeacher(String name, String quote, int image) {
            this.name = name;
            this.quote = quote;
            this.image = image;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getQuote() {
            return quote;
        }
        public int getImage() {
            return image;
        }

        public boolean isSelected() {
            return isSelected;
        }

        public void setSelected(boolean selected) {
            isSelected = selected;
        }
    }
    static class MyHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

            ImageView img;
            TextView nameTxt,posTxt;
            CheckBox myCheckBox;

            ItemClickListener itemClickListener;

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

                nameTxt= itemView.findViewById(R.id.nameTextView);
                posTxt= itemView.findViewById(R.id.descritionTextView);
                img= itemView.findViewById(R.id.teacherImageView);
                myCheckBox= itemView.findViewById(R.id.myCheckBox);

                myCheckBox.setOnClickListener(this);
            }
            public void setItemClickListener(ItemClickListener ic)
            {
                this.itemClickListener=ic;
            }
            @Override
            public void onClick(View v) {
                this.itemClickListener.onItemClick(v,getLayoutPosition());
            }
            interface ItemClickListener {

                void onItemClick(View v,int pos);
            }
        }
    static class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder> {

        Context c;
        SpiritualTeacher[] teachers;
        ArrayList<SpiritualTeacher> checkedTeachers=new ArrayList<>();

        public MyAdapter(Context c, SpiritualTeacher[] teachers) {
            this.c = c;
            this.teachers = teachers;
        }

        //VIEWHOLDER IS INITIALIZED
        @Override
        public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.model,null);
            MyHolder holder=new MyHolder(v);
            return holder;
        }

        //DATA IS BOUND TO VIEWS
        @Override
        public void onBindViewHolder(MyHolder holder, int position) {
            final SpiritualTeacher teacher=teachers[position];
            holder.nameTxt.setText(teacher.getName());
            holder.posTxt.setText(teacher.getQuote());
            holder.myCheckBox.setChecked(teacher.isSelected());
            holder.img.setImageResource(teacher.getImage());

            holder.setItemClickListener(new MyHolder.ItemClickListener() {
                @Override
                public void onItemClick(View v, int pos) {
                    CheckBox myCheckBox= (CheckBox) v;
                    SpiritualTeacher currentTeacher=teachers[pos];

                    if(myCheckBox.isChecked()) {
                        currentTeacher.setSelected(true);
                        checkedTeachers.add(currentTeacher);
                    }
                    else if(!myCheckBox.isChecked()) {
                        currentTeacher.setSelected(false);
                        checkedTeachers.remove(currentTeacher);
                    }
                }
            });
        }

        @Override
        public int getItemCount() {
            return teachers.length;
        }

    }
    private SpiritualTeacher[] getTeachers() {
        SpiritualTeacher[] spiritualTeachers={
                new SpiritualTeacher("Rumi","Out beyond ideas of wrongdoing and rightdoing there is a field.I'll meet you there.",R.drawable.rumi),
                new SpiritualTeacher("Anthony De Mello","Don't Carry Over Experiences from the past",R.drawable.anthony_de_mello),
                new SpiritualTeacher("Eckhart Tolle","Walk as if you are kissing the Earth with your feet.",R.drawable.eckhart_tolle),
                new SpiritualTeacher("Meister Eckhart","Man suffers only because he takes seriously what the gods made for fun.",R.drawable.meister_eckhart),
                new SpiritualTeacher("Mooji","I have lived with several Zen masters -- all of them cats.",R.drawable.mooji),
                new SpiritualTeacher("Confucius","I'm simply saying that there is a way to be sane. I'm saying that you ",R.drawable.confucius),
                new SpiritualTeacher("Francis Lucille","The way out is through the door. Why is it that no one will use this method?",R.drawable.francis_lucille),
                new SpiritualTeacher("Thich Nhat Hanh","t is the power of the mind to be unconquerable.",R.drawable.thich),
                new SpiritualTeacher("Dalai Lama","It's like you took a bottle of ink and you threw it at a wall. Smash! ",R.drawable.dalai_lama),
                new SpiritualTeacher("Jiddu Krishnamurti","A student, filled with emotion and crying, implored, 'Why is there so much suffering?",R.drawable.jiddu_krishnamurti),
                new SpiritualTeacher("Osho","Only the hand that erases can write the true thing.",R.drawable.osho),
                new SpiritualTeacher("Sedata","Many have died; you also will die. The drum of death is being beaten.",R.drawable.sedata),
                new SpiritualTeacher("Allan Watts","Where there are humans, You'll find flies,And Buddhas.",R.drawable.allant_watts),
                new SpiritualTeacher("Leo Gura","Silence is the language of Om. We need silence to be able to reach our Self.",R.drawable.sadhguru),
                new SpiritualTeacher("Rupert Spira","One day in my shoes and a day for me in your shoes, the beauty of travel lies ",R.drawable.rupert_spira),
                new SpiritualTeacher("Sadhguru","Like vanishing dew,a passing apparition or the sudden flashnof lightning",R.drawable.sadhguru)
        };

        return spiritualTeachers;
    }
    StringBuilder sb=null;
    MyAdapter adapter;

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

        adapter=new MyAdapter(this,getTeachers());

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                sb=new StringBuilder();

                int i=0;
                do {
                    SpiritualTeacher spiritualTeacher=adapter.checkedTeachers.get(i);
                    sb.append(spiritualTeacher.getName());
                    if(i != adapter.checkedTeachers.size()-1){
                        sb.append("n");
                    }
                    i++;

                }while (i < adapter.checkedTeachers.size());

                if(adapter.checkedTeachers.size()>0)
                {
                    Toast.makeText(MainActivity.this,sb.toString(),Toast.LENGTH_SHORT).show();
                }else
                {
                    Toast.makeText(MainActivity.this,"Please Check An Item First", Toast.LENGTH_SHORT).show();
                }
            }
        });

        //RECYCLER
        RecyclerView rv= (RecyclerView) findViewById(R.id.myRecycler);
        rv.setLayoutManager(new LinearLayoutManager(this));
        rv.setItemAnimator(new DefaultItemAnimator());

        //SET ADAPTER
        rv.setAdapter(adapter);

    }

}

Exemple 2 : SingleChoice RecyclerView - avec RadioButtons

Tutoriel Android SingleChoice RecyclerView (en anglais)

Dans ce tutoriel, nous voulons voir comment créer un recyclerview à choix unique. Il s'agit d'une vue de recyclage avec
boutons radio. L'utilisateur peut sélectionner un seul élément et nous ouvrons l'activité de détail de l'élément, montrant ainsi ses données.

Pourquoi une vue de recyclage à choix unique ?

L'alternative est une vue recyclée à choix multiples, c'est-à-dire une vue recyclée avec des cases à cocher. Cependant, dans certains cas
vous souhaitez simplement que l'utilisateur puisse sélectionner un seul élément dans la vue de recyclage. C'est là que les boutons radio entrent en jeu.

Cependant, dans notre cas, nous ouvrirons une activité détaillée lorsque l'utilisateur sélectionnera un bouton radio donné. Ensuite, nous utilisons des intents pour
transmettre des données à l'activité de détail.

Que montrons-nous ?

Eh bien, nous montrons des images, du texte et des boutons radios. Normalement, les images sont rendues dans imageview. Le texte
sera rendu dans textview. D'un autre côté, les boutons radios vont
montreront pour nous un état composé, essentiellement coché ou non.

Etape 1 : Scripts Gradle

(a) Build.gradle

Aucune dépendance particulière n'est requise. Nous ajoutons CardView et recyclerview comme dépendances.

Le CardView contiendra nos objets Galaxy. Le RecyclerView contiendra plusieurs CardViews. AppCompat nous donnera l'activité
AppCompatActivity à partir duquel notre MainActivity s'étend.

Etape 2 : créer des layouts

Nous avons trois mises en page

1. activité_main.xml

Ce layout sera gonflé dans MainActivity. Il contient simplement notre RecyclerView. J'ai donné au mien une
couleur de fond personnalisée.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    android_layout_width="match_parent"
    android_background="#009968"
    android_layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android_id="@+id/mRecylcerview"
        android_layout_width="match_parent"
        android_layout_height="match_parent" />
</RelativeLayout>

2. activité_detail.xml

La mise en page pour notre activité de détail. Contient des imageviews et textviews.to show
nos données.

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

    android_layout_width="match_parent"
    android_layout_height="match_parent"
    android_background="#009688"
    tools_context=".DetailsActivity"
    tools_showIn="@layout/activity_detail">

    <androidx.cardview.widget.CardView
        android_layout_width="match_parent"
        android_layout_height="match_parent"
        android_layout_margin="3dp"
        card_view_cardCornerRadius="3dp"
        card_view_cardElevation="5dp">

        <ScrollView
            android_layout_width="match_parent"
            android_layout_height="match_parent">

            <LinearLayout
                android_layout_width="match_parent"
                android_layout_height="match_parent"
                android_orientation="vertical">

                <ImageView
                    android_id="@+id/galaxyImg"
                    android_layout_width="match_parent"
                    android_layout_height="200dp"
                    android_layout_alignParentTop="true"
                    android_padding="5dp"
                    android_scaleType="fitXY"
                    android_src="@drawable/placeholder" />

                <LinearLayout
                    android_layout_width="match_parent"
                    android_layout_height="wrap_content"
                    android_orientation="vertical">

                    <LinearLayout
                        android_layout_width="match_parent"
                        android_layout_height="wrap_content"
                        android_orientation="horizontal">

                        <TextView
                            android_id="@+id/nameLabel"
                            android_layout_width="0dp"
                            android_layout_weight="1"
                            android_layout_height="wrap_content"
                            android_maxLines="1"
                            android_padding="5dp"
                            android_text="NAME"
                            android_textColor="@color/colorAccent"
                            android_textAppearance="?android:attr/textAppearanceSmall"
                            android_textStyle="bold" />

                        <TextView
                            android_id="@+id/nameTxt"
                            android_layout_width="0dp"
                            android_layout_weight="2"
                            android_layout_height="wrap_content"
                            android_maxLines="1"
                            android_padding="5dp"
                            android_text="Milky Way"
                            android_textAppearance="?android:attr/textAppearanceSmall"/>
                    </LinearLayout>

                    <LinearLayout
                        android_layout_width="match_parent"
                        android_layout_height="wrap_content"
                        android_orientation="horizontal">

                        <TextView
                            android_id="@+id/dateLabel"
                            android_layout_width="0dp"
                            android_layout_weight="1"
                            android_layout_height="wrap_content"
                            android_maxLines="1"
                            android_textColor="@color/colorAccent"
                            android_padding="5dp"
                            android_text="DATE"
                            android_textAppearance="?android:attr/textAppearanceSmall"
                            android_textStyle="bold" />

                        <TextView
                            android_id="@+id/dateDetailTextView"
                            android_layout_width="0dp"
                            android_layout_weight="2"
                            android_layout_height="wrap_content"
                            android_maxLines="1"
                            android_padding="5dp"
                            android_text="Today"
                            android_textAppearance="?android:attr/textAppearanceSmall"/>
                    </LinearLayout>

                    <LinearLayout
                        android_layout_width="match_parent"
                        android_layout_height="wrap_content"
                        android_orientation="horizontal">

                        <TextView
                            android_id="@+id/descLabel"
                            android_layout_width="0dp"
                            android_layout_weight="1"
                            android_layout_height="wrap_content"
                            android_maxLines="1"
                            android_textColor="@color/colorAccent"
                            android_padding="5dp"
                            android_text="DESCRIPTION : "
                            android_textAppearance="?android:attr/textAppearanceSmall"
                            android_textStyle="bold" />

                        <TextView
                            android_id="@+id/descTxt"
                            android_layout_width="0dp"
                            android_layout_weight="2"
                            android_layout_height="wrap_content"
                            android_maxLines="10"
                            android_padding="5dp"
                            android_text="Description..."
                            android_textAppearance="?android:attr/textAppearanceSmall"/>
                    </LinearLayout>

                </LinearLayout>
            </LinearLayout>
        </ScrollView>
    </androidx.cardview.widget.CardView>
</RelativeLayout>

3. model.xml

C'est notre mise en page de la vue des éléments. Il sera gonflé dans les éléments de notre vue recyclerview. Cela sera fait par notre RecyclerView
adaptateur.

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    android_orientation="horizontal" android_layout_width="match_parent"

    android_layout_margin="1dp"
    card_view_cardCornerRadius="1dp"
    card_view_cardElevation="5dp"
    android_layout_height="135dp">

        <RelativeLayout
            android_layout_width="wrap_content"
            android_layout_height="match_parent">

        <ImageView
            android_layout_width="120dp"
            android_layout_height="120dp"
            android_id="@+id/mGalaxyImageView"
            android_padding="5dp"
            android_scaleType="fitXY"
            android_src="@drawable/placeholder" />

        <TextView
            android_layout_width="wrap_content"
            android_layout_height="wrap_content"
            android_textAppearance="?android:attr/textAppearanceSmall"
            android_text="Name"
            android_id="@+id/mNameTxt"
            android_padding="5dp"
            android_textColor="@color/colorAccent"
            android_layout_alignParentTop="true"
            android_layout_toRightOf="@+id/mGalaxyImageView" />

        <TextView
            android_layout_width="wrap_content"
            android_layout_height="wrap_content"
            android_textAppearance="?android:attr/textAppearanceSmall"
            android_text="Description"
            android_textStyle="italic"
            android_maxLines="3"
            android_id="@+id/mDescTxt"
            android_padding="5dp"
            android_layout_alignBottom="@+id/mGalaxyImageView"
            android_layout_toRightOf="@+id/mGalaxyImageView" />

            <RadioButton
                android_id="@+id/mRadioButton"
                android_layout_width="wrap_content"
                android_layout_height="wrap_content"
                android_layout_alignParentRight="true" />

        </RelativeLayout>
</androidx.cardview.widget.CardView>

Étape 4 : Écrire le code Java.

Nous avons les classes java suivantes pour ce projet :

  1. Galaxy.java
  2. RecyclerAdapter.java
  3. DetailsActivity.java
  4. MainActivity.java
(a).Galaxy.java

Ceci représentera notre objet de données. C'est notre classe modèle et elle représente une galaxie avec des propriétés telles que :

  1. Nom.
  2. Description
  3. Image.

Voici le code complet.

package info.camposha.singlechoicerecyclerview_vela;

import java.io.Serializable;

/**
 * Please take note that our data object will implement Serializable.This
 * will allow us to pass this serialized object to DetailsActivity,
 */
public class Galaxy implements Serializable{
    private String name,description;
    private int image;

    public Galaxy(String name, String description,int image) {
        this.name = name;
        this.description = description;
        this.image=image;
    }

    public String getName() {return name;}
    public String getDescription() {return description;}
    public int getImage() {return image;}

}

Vous pouvez voir que nous avons implémenté l'interface Serializable. Cela nous permet de sérialiser notre objet de données afin
qu'il puisse être transporté vers l'activité DetailsActivity dans son ensemble via l'intention.

(b). RecyclerAdapter.java

Il s'agit de notre classe d'adaptateur. Elle va gonfler notre modèle de mise en page en un objet de vue qui peut être rendu par le recyclerview.
Elle va également lier les données à ces objets de vue gonflés.

package info.camposha.singlechoicerecyclerview_vela;

import android.content.Context;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.TextView;

import java.util.List;

public class RecyclerAdapter extends RecyclerView.Adapter<
RecyclerAdapter.RecyclerViewHolder> {

    /**
     * Let's start by defining our instance fields
     */
    private int selectedStarPosition = -1;
    private List<Galaxy> galaxies;
    private Context c;
    private AdapterView.OnItemClickListener onItemClickListener;

    /**
     * Let's create our constructor
     * @param context
     * @param mGalaxies
     */
    public RecyclerAdapter(Context context, List<Galaxy> mGalaxies) {
        this.c = context;
        this.galaxies = mGalaxies;
    }

    /**
     * OnCreateViewHolder - here is where we inflate our model layout
     * @param viewGroup
     * @param i
     * @return
     */
    @Override
    public RecyclerViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        final View v = LayoutInflater.from(c).inflate(R.layout.model, viewGroup, false);
        return new RecyclerViewHolder(v, this);
    }

    /**
     * OnBindViewHolder - Here's where we bind our data
     * @param viewHolder
     * @param position
     */
    @Override
    public void onBindViewHolder(RecyclerViewHolder viewHolder, final int position) {
        Galaxy galaxy = galaxies.get(position);
        try {
            viewHolder.bindData(galaxy, position);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * Let's return the number of items to be bound to our adapter.
     * @return
     */
    @Override
    public int getItemCount() {
        return galaxies.size();
    }

    /**
     * Let's receive our onItemClickListener and assign it to our local one.
     * @param onItemClickListener
     */
    public void setOnItemClickListener(AdapterView.OnItemClickListener
     onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    /**
     * When user clicks our itemView, we still invoke the onItemClick
     * @param holder
     */
    public void onItemHolderClick(RecyclerViewHolder holder) {
        if (onItemClickListener != null)
            onItemClickListener.onItemClick(null, holder.itemView,
             holder.getAdapterPosition(), holder.getItemId());
    }

    /**
     * Let's come create our ViewHolder class.
     */
    class RecyclerViewHolder extends RecyclerView.ViewHolder implements
     View.OnClickListener {

        private RecyclerAdapter mAdapter;
        private RadioButton mRadioButton;
        private TextView mNameTxt,mDescTxt;
        private ImageView mGalaxyImg;

        /**
         * In our constructor, we reference our itemView widgets.
         * @param itemView
         * @param mAdapter
         */
        public RecyclerViewHolder(View itemView, final RecyclerAdapter mAdapter) {
            super(itemView);
            this.mAdapter = mAdapter;

            mNameTxt = itemView.findViewById(R.id.mNameTxt);
            mDescTxt = itemView.findViewById(R.id.mDescTxt);
            mRadioButton = itemView.findViewById(R.id.mRadioButton);
            mGalaxyImg=itemView.findViewById(R.id.mGalaxyImageView);
            itemView.setOnClickListener(this);
            mRadioButton.setOnClickListener(this);
        }

        /**
         * Let's create a method that allows us bind our data.
         * @param galaxy
         * @param position
         */
        public void bindData(Galaxy galaxy, int position) {
            mRadioButton.setChecked(position == selectedStarPosition);
            mNameTxt.setText(galaxy.getName());
            mDescTxt.setText(galaxy.getDescription());
            mGalaxyImg.setImageResource(galaxy.getImage());
        }

        /**
         * Let's override our OnClick method.
         * @param v
         */
        @Override
        public void onClick(View v) {
            selectedStarPosition = getAdapterPosition();
            notifyItemRangeChanged(0, galaxies.size());
            mAdapter.onItemHolderClick(RecyclerViewHolder.this);
        }
    }
}
//end
(c). DetailsActivity.java

Notre classe d'activité de détail. Cela montrera les détails de la galaxie cliquée.

package info.camposha.singlechoicerecyclerview_vela;

import android.content.Intent;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.widget.ImageView;
import android.widget.TextView;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DetailsActivity extends AppCompatActivity {

  TextView nameTxt, descTxt, dateDetailTextView;
  ImageView galaxyImg;

  //We start by initializing our widgets.
  private void initializeWidgets() {
    nameTxt = findViewById(R.id.nameTxt);
    descTxt = findViewById(R.id.descTxt);
    dateDetailTextView = findViewById(R.id.dateDetailTextView);
    descTxt = findViewById(R.id.descTxt);
    galaxyImg = findViewById(R.id.galaxyImg);
  }

  //This method will get todays date and return it as a string
  private String getDateToday() {
    DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
    Date date = new Date();
    String today = dateFormat.format(date);
    return today;
  }

  //I'll create a method to receive and show data.
  private void receiveAndShowData() {
    //RECEIVE DATA FROM ITEMS ACTIVITY VIA INTENT
    Intent i = this.getIntent();
    Galaxy g= (Galaxy) i.getSerializableExtra("GALAXY_KEY");

    //SET RECEIVED DATA TO TEXTVIEWS AND IMAGEVIEWS
    nameTxt.setText(g.getName());
    descTxt.setText(g.getDescription());
    dateDetailTextView.setText(getDateToday());
    galaxyImg.setImageResource(g.getImage());
  }

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

    initializeWidgets();
    receiveAndShowData();
  }
}
//end
(d). MainActivity.java

Notre classe d'activité principale. C'est ici que nous référençons notre recyclerview et que nous définissons notre source de données.

package info.camposha.singlechoicerecyclerview_vela;

import android.content.Intent;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Toast;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {

    RecyclerView mRecyclerView;
    private RecyclerAdapter mAdapter;
    /**
     * Let's start by defining our data source.
     * @return
     */
    private ArrayList<Galaxy> getData()
    {
        ArrayList<Galaxy> galaxies=new ArrayList<>();
        Galaxy g=new Galaxy("Whirlpool",
                "The Whirlpool Galaxy, also known as Messier 51a, M51a, and NGC 5194, is an interacting grand-design spiral Galaxy with a Seyfert 2 active galactic nucleus in the constellation Canes Venatici.",
                R.drawable.whirlpool);
        galaxies.add(g);

        g=new Galaxy("Ring Nebular",
                "The Ring Nebula is a planetary nebula in the northern constellation of Lyra. Such objects are formed when a shell of ionized gas is expelled into the surrounding interstellar medium by a red giant star.",
                R.drawable.ringnebular);
        galaxies.add(g);

        g=new Galaxy("IC 1011",
                "C 1011 is a compact elliptical galaxy with apparent magnitude of 14.7, and with a redshift of z=0.02564 or 0.025703, yielding a distance of 100 to 120 Megaparsecs. Its light has taken 349.5 million years to travel to Earth.",
                R.drawable.ic1011);
        galaxies.add(g);

        g=new Galaxy("Cartwheel",
                "The Cartwheel Galaxy is a lenticular galaxy and ring galaxy about 500 million light-years away in the constellation Sculptor. It is an estimated 150,000 light-years diameter, and a mass of about 2.9–4.8 × 10⁹ solar masses; it rotates at 217 km/s.",
                R.drawable.cartwheel);
        galaxies.add(g);

        g=new Galaxy("Triangulumn",
                "The Triangulum Galaxy is a spiral Galaxy approximately 3 million light-years from Earth in the constellation Triangulum",
                R.drawable.triangulum);
        galaxies.add(g);

        g=new Galaxy("Small Magellonic Cloud",
                "The Small Magellanic Cloud, or Nubecula Minor, is a dwarf galaxy near the Milky Way. It is classified as a dwarf irregular galaxy.",
                R.drawable.smallamgellonic);
        galaxies.add(g);

        g=new Galaxy("Centaurus A",
                " Centaurus A or NGC 5128 is a galaxy in the constellation of Centaurus. It was discovered in 1826 by Scottish astronomer James Dunlop from his home in Parramatta, in New South Wales, Australia.",
                R.drawable.centaurusa);
        galaxies.add(g);

        g=new Galaxy("Ursa Minor",
                "The Milky Way is the Galaxy that contains our Solar System." +
                        " The descriptive milky is derived from the appearance from Earth of the Galaxy – a band of light seen in the night sky formed from stars",
                R.drawable.ursaminor);
        galaxies.add(g);

        g=new Galaxy("Large Magellonic Cloud",
                " The Large Magellanic Cloud is a satellite galaxy of the Milky Way. At a distance of 50 kiloparsecs, the LMC is the third-closest galaxy to the Milky Way, after the Sagittarius Dwarf Spheroidal and the.",
                R.drawable.largemagellonic);
        galaxies.add(g);

        g=new Galaxy("Milky Way",
                "The Milky Way is the Galaxy that contains our Solar System." +
                        " The descriptive milky is derived from the appearance from Earth of the Galaxy – a band of light seen in the night sky formed from stars",
                R.drawable.milkyway);
        galaxies.add(g);

        g=new Galaxy("Andromeda",
                "The Andromeda Galaxy, also known as Messier 31, M31, or NGC 224, is a spiral Galaxy approximately 780 kiloparsecs from Earth. It is the nearest major Galaxy to the Milky Way and was often referred to as the Great Andromeda Nebula in older texts.",
                R.drawable.andromeda);
        galaxies.add(g);

        g=new Galaxy("Messier 81",
                "Messier 81 is a spiral Galaxy about 12 million light-years away in the constellation Ursa Major. Due to its proximity to Earth, large size and active galactic nucleus, Messier 81 has been studied extensively by professional astronomers.",
                R.drawable.messier81);
        galaxies.add(g);

        g=new Galaxy("Own Nebular",
                " The Owl Nebula is a planetary nebula located approximately 2,030 light years away in the constellation Ursa Major. It was discovered by French astronomer Pierre Méchain on February 16, 1781",
                R.drawable.ownnebular);
        galaxies.add(g);

        g=new Galaxy("Messier 87",
                "Messier 87 is a supergiant elliptical galaxy in the constellation Virgo. One of the most massive galaxies in the local universe, it is notable for its large population of globular clusters—M87 contains",
                R.drawable.messier87);
        galaxies.add(g);

        g=new Galaxy("Cosmos Redshift",
                "Cosmos Redshift 7 is a high-redshift Lyman-alpha emitter Galaxy, in the constellation Sextans, about 12.9 billion light travel distance years from Earth, reported to contain the first stars —formed ",
                R.drawable.cosmosredshift);
        galaxies.add(g);

        g=new Galaxy("StarBust",
                "A starburst Galaxy is a Galaxy undergoing an exceptionally high rate of star formation, as compared to the long-term average rate of star formation in the Galaxy or the star formation rate observed in most other galaxies. ",
                R.drawable.starbust);
        galaxies.add(g);

        g=new Galaxy("Sombrero",
                "Sombrero Galaxy is an unbarred spiral galaxy in the constellation Virgo located 31 million light-years from Earth. The galaxy has a diameter of approximately 50,000 light-years, 30% the size of the Milky Way.",
                R.drawable.sombrero);
        galaxies.add(g);

        g=new Galaxy("Pinwheel",
                "The Pinwheel Galaxy is a face-on spiral galaxy distanced 21 million light-years away from earth in the constellation Ursa Major. ",
                R.drawable.pinwheel);
        galaxies.add(g);

        g=new Galaxy("Canis Majos Overdensity",
                "The Canis Major Dwarf Galaxy or Canis Major Overdensity is a disputed dwarf irregular galaxy in the Local Group, located in the same part of the sky as the constellation Canis Major. ",
                R.drawable.canismajoroverdensity);
        galaxies.add(g);

        g=new Galaxy("Virgo Stella Stream",
                " Group, located in the same part of the sky as the constellation Canis Major. ",
                R.drawable.virgostellarstream);
        galaxies.add(g);

        return galaxies;
    }

    /**
     * Let's create a method to open our detail activity and pass our object.
     * @param galaxy
     */
    private void openDetailActivity(Galaxy galaxy)
    {
        Intent i=new Intent(this,DetailsActivity.class);
        i.putExtra("GALAXY_KEY",galaxy);
        startActivity(i);
    }

    /**
     * Let's implemenent our onItemClick method
     * @param parent
     * @param view
     * @param position
     * @param id
     */
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Galaxy g=getData().get(position);
        Toast.makeText(MainActivity.this,String.valueOf(position)+". "+ g.getName()+" Chosen.", Toast.LENGTH_SHORT).show();
        openDetailActivity(g);
    }

    /**
     * Let's override our onCreate callback
     * @param savedInstanceState
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mRecyclerView=findViewById(R.id.mRecylcerview);

        mAdapter = new RecyclerAdapter(this, getData());
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mRecyclerView.setAdapter(mAdapter);
        mAdapter.setOnItemClickListener(this);
    }
}
Télécharger

Vous pouvez télécharger le code source complet ci-dessous ou regarder la vidéo à partir du lien fourni.

No. Location Link
1. GitHub Direct Download
2. GitHub Browse
3. YouTube Video Tutorial
4. YouTube ProgrammingWizards TV Channel

Exemple 3 : Kotlin Android RecyclerView - CardView avec CheckBox,Images,Texte et ItemClick

Kotlin Android RecyclerView avec CheckBoxes, Images, texte et ItemClick supporte Tutorial et Exemple.

Je veux vous montrer comment vous pouvez travailler avec le recyclerview dans ce tutoriel et faire des choses communes comme l'utiliser avec des checkboxes, des images, des textviews et aussi supporter les événements de clic. Tout cela se fait dans un seul fichier MainActivity.kt.

Tutoriel vidéo

Si vous préférez un tutoriel vidéo, cliquez ici :

Ce que vous apprenez

Voici les concepts que vous apprendrez :

  1. Comment utiliser Recyclerview dans android avec le langage de programmation Kotlin.
  2. Comment utiliser CheckBox avec recyclerview et gérer les états de checkbox de manière appropriée.
  3. Comment créer un recyclerview avec des images et du texte.
  4. Comment prendre en charge l'événement de clic sur l'élément dans le recyclerview.

Outils utilisés

Voici les outils que j'ai utilisés pour ce projet :

  1. Langage de programmation : Kotlin
  2. Framework : Android
  3. IDE - Android Studio.
  4. Emulateur - Nox Player
  5. SYSTÈME D'EXPLOITATION : Windows 8.1

Commençons.

Demo

Voici la démo de ce projet :


Kotlin RecyclerView CheckBox

(a). Build.gradle

Notre niveau d'application build.gradle.
C'est ici que nous ajoutons nos dépendances. En particulier, nous sommes intéressés par trois principales d'entre elles :

  1. AppCompat - Pour nous donner l'AppCompatActivity dont notre MainActivity dérivera.
  2. Design Support - Pour nous donner le RecyclerView.
  3. CardView - Pour nous donner Cardview.

(b). activity_main.xml

Il s'agit de la mise en page principale de notre [activité] (https://camposha.info/android/activity). Voici les composants que nous utilisons :

  1. RelativeLayout - Pour disposer nos autres widgets les uns par rapport aux autres.
  2. TextView - Pour rendre le texte de l'en-tête.
  3. RecyclerView - Pour rendre nos données.
  4. Bouton d'action flottant - Pour afficher les éléments cochés lorsqu'on clique dessus.

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

    android_layout_width="match_parent"
    android_layout_height="match_parent"
    tools_context="com.devosha.kotlin_recyclerview_checkbox.MainActivity">

    <TextView
        android_id="@+id/headerTextView"
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_text="Spiritual Teachers"
        android_textAlignment="center"
        android_textAppearance="@style/TextAppearance.AppCompat.Large"
        android_textColor="@color/colorAccent" />

    <androidx.recyclerview.widget.RecyclerView
        android_id="@+id/myRecycler"
        class="androidx.recyclerview.widget.RecyclerView"
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_layout_alignParentLeft="true"
        android_layout_alignParentStart="true"
        android_layout_below="@+id/headerTextView"
        android_layout_marginTop="30dp" />

    <android.support.design.widget.FloatingActionButton
        android_id="@+id/fab"
        android_layout_width="wrap_content"
        android_layout_height="wrap_content"
        android_layout_alignParentBottom="true"
        android_layout_alignParentEnd="true"
        android_layout_alignParentRight="true"
        android_layout_gravity="bottom|end"
        android_src="@android:drawable/ic_dialog_email" />

</RelativeLayout>

(c). model.xml

Ce layout va définir nos vues d'articles pour notre recyclerview, il va les modéliser. En gros, il va rendre les données pour un seul objet SpiritualTeacher. A la racine, nous avons un CardView. Puis nous avons aussi :

  1. ImageView - Pour rendre l'image de l'objet SpiritualTeacher.
  2. TextVIew - Pour rendre son nom ainsi que sa description.
  3. CheckBox - Pour nous permettre de sélectionner et désélectionner les CardViews.

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    android_orientation="horizontal" android_layout_width="match_parent"

    android_layout_margin="5dp"
    card_view_cardCornerRadius="10dp"
    card_view_cardElevation="5dp"
    android_layout_height="match_parent">

    <RelativeLayout
        android_layout_width="match_parent"
        android_layout_height="match_parent">
        <ImageView
            android_layout_width="150dp"
            android_layout_height="150dp"
            android_id="@+id/teacherImageView"
            android_padding="5dp"
            android_src="@drawable/cle" />

        <TextView
            android_layout_width="wrap_content"
            android_layout_height="wrap_content"
            android_textAppearance="?android:attr/textAppearanceLarge"
            android_text="Teacher Name"
            android_id="@+id/nameTextView"
            android_padding="5dp"
            android_textColor="@color/colorAccent"
            android_layout_alignParentTop="true"
            android_layout_toRightOf="@+id/teacherImageView" />

        <TextView
            android_layout_width="wrap_content"
            android_layout_height="wrap_content"
            android_textAppearance="?android:attr/textAppearanceMedium"
            android_text="Teacher Description..."
            android_id="@+id/descritionTextView"
            android_padding="5dp"
            android_layout_alignBottom="@+id/teacherImageView"
            android_layout_toRightOf="@+id/teacherImageView" />

        <CheckBox
            android_layout_width="wrap_content"
            android_layout_height="wrap_content"
            android_id="@+id/myCheckBox"
            android_layout_alignParentRight="true"
            />

    </RelativeLayout>
</androidx.cardview.widget.CardView>

(d). MainActivity.kt

C'est notre [activité] principale (https://camposha.info/android/activity). C'est notre seul fichier et nous allons définir plusieurs classes kotlin internes ici. Cette classe sera dérivée de l'AppCompatActivity.

Créer un objet de données

Nous allons commencer par définir une classe interne appelée SpiritualTeacher :

   inner class SpiritualTeacher(var name: String?, val quote: String, val image: Int) {
        var isSelected: Boolean = false
    }

Cette classe est notre objet de données. Elle recevra ses paramètres via le constructeur. De plus nous maintenons un simple booléen comme vous pouvez le voir qui va contenir pour nous l'état de sélection des CardViews. En fait, c'est la magie qui nous permet de sélectionner et de désélectionner nos éléments dans notre vue recyclée. Ainsi, notre vue recyclée ne perdra pas son état, même si nous faisons défiler la page et que les éléments de la vue recyclée sont recyclés. Cela est dû au fait que nous les conservons en tant que données dans notre objet et qu'ils ne sont pas affectés par le recyclage.

Créer la classe d'adaptateur RecyclerVew

Normalement, l'adaptateur a deux rôles principaux. D'abord pour gonfler nos mises en page personnalisées et ensuite pour lier les données aux widgets résultants. Cependant, Recyclerview va toujours plus loin en nous permettant de recycler les éléments. Cela permet d'économiser de la mémoire, car le gonflage est un processus coûteux et aurait un impact négatif sur notre application si nous devions le faire pour chaque élément dans le recyclerview.

Nous allons donc créer un adaptateur :

    internal class MyAdapter(var c: Context, var teachers: Array<SpiritualTeacher>) : RecyclerView.Adapter<MyAdapter.MyHolder>() {..}

Nous l'avons fait dériver de la classe RecyclerView.Adapter.

A l'intérieur de l'adaptateur, nous allons d'abord créer un arraylist qui contiendra pour nous les enseignants qui ont été vérifiés :

        var checkedTeachers = ArrayList<SpiritualTeacher>()

C'est dans la méthode onCreateViewHolder() que nous allons gonfler notre model.xml en un objet View. Pour cela, nous utilisons la classe LayoutInflater.

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyHolder {
            val v = LayoutInflater.from(parent.context).inflate(R.layout.model, null)
            return MyHolder(v)
        }

Voici le code source complet.

package com.devosha.kotlin_recyclerview_checkbox

import android.content.Context
import android.os.Bundle
import android.support.design.widget.FloatingActionButton
import androidx.appcompat.app.AppCompatActivity
import android.support.v7.widget.DefaultItemAnimator
import android.support.v7.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.CheckBox
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast

import java.util.ArrayList

/**
 * class: MainActivity
 * This class is deriving from androidx.appcompat.app.AppCompatActivity.
 */
class MainActivity : AppCompatActivity() {

    private val teachers: Array<SpiritualTeacher>
        get() =
            arrayOf(SpiritualTeacher("Rumi", "Out beyond ideas of wrongdoing and rightdoing there is a field.I'll meet you there.", R.drawable.rumi),
                    SpiritualTeacher("Anthony De Mello", "Don't Carry Over Experiences from the past", R.drawable.anthony_de_mello),
                    SpiritualTeacher("Eckhart Tolle", "Walk as if you are kissing the Earth with your feet.", R.drawable.eckhart_tolle),
                    SpiritualTeacher("Meister Eckhart", "Man suffers only because he takes seriously what the gods made for fun.", R.drawable.meister_eckhart),
                    SpiritualTeacher("Mooji", "I have lived with several Zen masters -- all of them cats.", R.drawable.mooji),
                    SpiritualTeacher("Confucius", "I'm simply saying that there is a way to be sane. I'm saying that you ", R.drawable.confucius),
                    SpiritualTeacher("Francis Lucille", "The way out is through the door. Why is it that no one will use this method?", R.drawable.francis_lucille),
                    SpiritualTeacher("Thich Nhat Hanh", "t is the power of the mind to be unconquerable.", R.drawable.thich),
                    SpiritualTeacher("Dalai Lama", "It's like you took a bottle of ink and you threw it at a wall. Smash! ", R.drawable.dalai_lama),
                    SpiritualTeacher("Jiddu Krishnamurti", "A student, filled with emotion and crying, implored, 'Why is there so much suffering?", R.drawable.jiddu_krishnamurti),
                    SpiritualTeacher("Osho", "Only the hand that erases can write the true thing.", R.drawable.osho),
                    SpiritualTeacher("Sedata", "Many have died; you also will die. The drum of death is being beaten.", R.drawable.sedata),
                    SpiritualTeacher("Allan Watts", "Where there are humans, You'll find flies,And Buddhas.", R.drawable.allant_watts),
                    SpiritualTeacher("Leo Gura", "Silence is the language of Om. We need silence to be able to reach our Self.", R.drawable.sadhguru),
                    SpiritualTeacher("Rupert Spira", "One day in my shoes and a day for me in your shoes, the beauty of travel lies ", R.drawable.rupert_spira),
                    SpiritualTeacher("Sadhguru", "Like vanishing dew,a passing apparition or the sudden flashnof lightning", R.drawable.sadhguru))
    internal var sb: StringBuilder? = null
    internal lateinit var adapter: MyAdapter

    inner class SpiritualTeacher(var name: String?, val quote: String, val image: Int) {
        var isSelected: Boolean = false
    }

    internal class MyAdapter(var c: Context, var teachers: Array<SpiritualTeacher>) : RecyclerView.Adapter<MyAdapter.MyHolder>() {
        var checkedTeachers = ArrayList<SpiritualTeacher>()

        //VIEWHOLDER IS INITIALIZED
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyHolder {
            val v = LayoutInflater.from(parent.context).inflate(R.layout.model, null)
            return MyHolder(v)
        }

        //DATA IS BOUND TO VIEWS
        override fun onBindViewHolder(holder: MyHolder, position: Int) {
            val teacher = teachers[position]
            holder.nameTxt.text = teacher.name
            holder.posTxt.text = teacher.quote
            holder.myCheckBox.isChecked = teacher.isSelected
            holder.img.setImageResource(teacher.image)

            holder.setItemClickListener(object : MyHolder.ItemClickListener {
                override fun onItemClick(v: View, pos: Int) {
                    val myCheckBox = v as CheckBox
                    val currentTeacher = teachers[pos]

                    if (myCheckBox.isChecked) {
                        currentTeacher.isSelected = true
                        checkedTeachers.add(currentTeacher)
                    } else if (!myCheckBox.isChecked) {
                        currentTeacher.isSelected = false
                        checkedTeachers.remove(currentTeacher)
                    }
                }
            })
        }

        override fun getItemCount(): Int {
            return teachers.size
        }

        internal class MyHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener {

            var img: ImageView
            var nameTxt: TextView
            var posTxt: TextView
            var myCheckBox: CheckBox

            lateinit var myItemClickListener: ItemClickListener

            init {

                nameTxt = itemView.findViewById(R.id.nameTextView)
                posTxt = itemView.findViewById(R.id.descritionTextView)
                img = itemView.findViewById(R.id.teacherImageView)
                myCheckBox = itemView.findViewById(R.id.myCheckBox)

                myCheckBox.setOnClickListener(this)
            }

            fun setItemClickListener(ic: ItemClickListener) {
                this.myItemClickListener = ic
            }

            override fun onClick(v: View) {
                this.myItemClickListener.onItemClick(v, layoutPosition)
            }

            internal interface ItemClickListener {

                fun onItemClick(v: View, pos: Int)
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        adapter = MyAdapter(this, teachers)

        val fab = findViewById(R.id.fab) as FloatingActionButton
        fab.setOnClickListener {
            sb = StringBuilder()

            var i = 0
            while (i < adapter.checkedTeachers.size) {
                val spiritualTeacher = adapter.checkedTeachers[i]
                sb!!.append(spiritualTeacher.name)
                if (i != adapter.checkedTeachers.size - 1) {
                    sb!!.append("n")
                }
                i++

            }

            if (adapter.checkedTeachers.size > 0) {
                Toast.makeText(this@MainActivity, sb!!.toString(), Toast.LENGTH_SHORT).show()
            } else {
                Toast.makeText(this@MainActivity, "Please Check An Item First", Toast.LENGTH_SHORT).show()
            }
        }

        //RECYCLER
        val rv = findViewById(R.id.myRecycler) as RecyclerView
        rv.layoutManager = LinearLayoutManager(this)
        rv.itemAnimator = DefaultItemAnimator()

        //SET ADAPTER
        rv.adapter = adapter

    }
// end
}

Exemple 4 : Android MySQL - RecyclerView CheckBoxes - INSERT,SELECT,SHOW

*Voici un tutoriel Android MySQL sur les vues de recyclage avec cases à cocher. Nous voyons comment travailler avec des valeurs textuelles et booléennes avec notre base de données mysql.

  • Aujourd'hui, nous explorons comment travailler avec des valeurs booléennes et textuelles avec MySQL et RecyclerView.
  • Tout d'abord, nous insérons des données dans la base de données MySQL.
  • Les composants que nous utilisons en tant que vues d'entrée sont la boîte à lettres, la roue et le texte d'édition du matériel.
  • L'utilisateur tape le nom de son vaisseau spatial favori dans le texte d'édition, puis sélectionne l'agent propulseur de ce vaisseau dans une roue.
  • Il coche/décoche ensuite une case pour indiquer si cette technologie existe ou non.
  • Nous sauvegardons ces données dans MySQL en cliquant sur le bouton.
  • Lors du clic sur le bouton 'retrieve', nous sélectionnons les données de MySQL et lions ce texte et ces booléens à notre Checked RecyclerView, RecyclerView avec CheckBoxes.

Tout d'abord, permettez-moi de dire que nous avons le code source complet et bien commenté ci-dessus à télécharger comme référence complète. Nous avons inclus le fichier PHP que nous avons utilisé. Vous le placerez dans le répertoire racine de votre serveur et modifierez des choses comme le nom d'utilisateur, le nom de la table, etc.

Tutoriel vidéo (Chaîne TV ProgrammingWizards)

Nous vous proposons un tutoriel vidéo comme alternative à cette méthode. Si vous préférez les tutoriels comme celui-ci, il serait bon de vous [abonner à notre chaîne YouTube] (https://www.youtube.com/channel/UCpdkWp2zh5Qv1ZWlnqswdCw).

En fait, nous avons une chaîne de télévision consacrée à la programmation qui propose des tutoriels quotidiens, notamment sur Android.

Android MySQL RecyclerView CheckBoxes Insert, Select Show Exemple

Regardons notre exemple :

!Android MySQL RecyclerView](https://github.com/Oclemy/MySQL-Recycler-Boolean/raw/master/demos/MySQLRecyclerView.PNG)

Table MySQL

Voici la structure de notre table MySQL :

Structure de la table

Structure du projet

Voici la structure de notre projet.

Structure du projet

1. Code PHP

Voici notre code php :

(a) Constants.php

Notre classe PHP pour contenir les constantes de la base de données comme le nom du serveur, le nom de la base de données, le nom d'utilisateur et le mot de passe. Ces informations d'identification seront nécessaires pour que nous puissions nous connecter à la base de données MySQL.

<?php

class Constants
{
    //DATABASE DETAILS
    static $DB_SERVER="localhost";
    static $DB_NAME="galileoDB";
    static $USERNAME="root";
    static $PASSWORD="";
    const TB_NAME="galileoTB";
    //STATEMENTS
    static $SQL_SELECT_ALL="SELECT * FROM galileoTB";
}
(b) CRUD.php

Ce fichier PHP va nous permettre de recevoir des données du client HTTP en écoutant et en traitant les requêtes. Nous traitons ces requêtes en initiant les actions CRUD définies dans notre classe DBAdapater.php.

<?php

require_once("/DBAdapter.php");
if($_POST['action']=="save"){

         $dbAdapter=new DBAdapter();
         $name=$_POST['name'];
         $propellant=$_POST['propellant'];
         $technologyexists=$_POST['technologyexists'];
        $dbAdapter->insert(array($name,$propellant,$technologyexists));
}
else if($_POST['action']=="update")
{
         $dbAdapter=new DBAdapter();
         $id=$_POST['id'];
         $name=$_POST['name'];
         $propellant=$_POST['propellant'];
         $technologyexists=$_POST['technologyexists'];
        $dbAdapter->update($id,array($name,$propellant,$technologyexists));

}
else if($_POST['action']=="delete")
{
         $dbAdapter=new DBAdapter();
         $id=$_POST['id'];

        $dbAdapter->delete($id);
}
?>
(c) DBAdapter.php

Ce fichier PHP contiendra des fonctions qui nous permettront d'effectuer des opérations CRUD sur notre base de données MySQL. Ces actions comprennent l'insertion et la récupération de données vers et depuis la base de données.

<?php

require_once("/Constants.php");
class DBAdapter
{
/*******************************************************************************************************************************************/
/*
   1.CONNECT TO DATABASE.
   2. RETURN CONNECTION OBJECT
*/
    public function connect()
    {

       $con=mysqli_connect(Constants::$DB_SERVER,Constants::$USERNAME,Constants::$PASSWORD,Constants::$DB_NAME);
        if(mysqli_connect_error(!$con))
        {
           // echo "Unable To Connect";
            return null;
        }else
        {

            return $con;
        }
    }
    /*******************************************************************************************************************************************/
/*
   1.INSERT SPACECRAFT INTO DATABASE
 */
    public function insert($s)
    {
        // INSERT
        $con=$this->connect();

        if($con != null)
        {
            $sql="INSERT INTO galileoTB(name,propellant,technologyexists) VALUES('$s[0]','$s[1]','$s[2]')";
            try
            {
                $result=mysqli_query($con,$sql);
                if($result)
                {
                    print(json_encode(array("Success")));
                }else
                {
                    print(json_encode(array("Unsuccessfull")));
                }
            }catch (Exception $e)
            {
               print(json_encode(array("PHP EXCEPTION : CAN'T SAVE TO MYSQL. "+$e->getMessage())));
            }
        }else{
            print(json_encode(array("PHP EXCEPTION : CAN'T CONNECT TO MYSQL. NULL CONNECTION.")));
        }
        mysqli_close($con);
    }
/*******************************************************************************************************************************************/
/*
   1.SELECT FROM DATABASE.
*/
    public function select()
    {
       $con=$this->connect();
        if($con != null)
        {
            $retrieved=mysqli_query($con,Constants::$SQL_SELECT_ALL);
            if($retrieved)
            {
                while($row=mysqli_fetch_array($retrieved))
                {

                   // echo $row["name"] ,"    t | ",$row["propellant"],"</br>";
                   $spacecrafts[]=$row;
                }
                print(json_encode($spacecrafts));
            }else
            {
                 print(json_encode(array("PHP EXCEPTION : CAN'T RETRIEVE FROM MYSQL. ")));
            }
        }else{
            print(json_encode(array("PHP EXCEPTION : CAN'T CONNECT TO MYSQL. NULL CONNECTION.")));
        }
        mysqli_close($con);
    }
/*******************************************************************************************************************************************/
/*
   1.UPDATE  DATABASE.

*/
    public function update($id, $s)
    {
        // UPDATE
        $con=$this->connect();

        if($con != null)
        {
            $sql="UPDATE galileoTB SET name='$s[0]',propellant='$s[1]',technologyexists='$s[2]' WHERE id='$id'";
            try
            {
                $result=mysqli_query($con,$sql);
                if($result)
                {
                    print(json_encode(array("Successfully Updated")));
                }else
                {
                    print(json_encode(array("Not Successfully Updated")));
                }
            }catch (Exception $e)
            {
                 print(json_encode(array("PHP EXCEPTION : CAN'T UPDATE INTO MYSQL. "+$e->getMessage())));
            }
        }else{
            print(json_encode(array("PHP EXCEPTION : CAN'T CONNECT TO MYSQL. NULL CONNECTION.")));
        }
        mysqli_close($con);
    }
/*******************************************************************************************************************************************/
/*
   1.DELETE SPACECRAFT FROM DATABASE.

*/
    public function delete($id)
    {
        $con=$this->connect();

        if($con != null)
        {
//            $name=$_POST['Name'];
//            $pos=$_POST['Position'];
//            $team=$_POST['Team'];
            $sql="DELETE FROM galileoTB WHERE id='$id'";
            try
            {
                $result=mysqli_query($con,$sql);
                if($result)
                {
                    print(json_encode(array("Successfully Deleted")));
                }else
                {
                    print(json_encode(array("Not Successfully Deleted")));
                }
            }catch (Exception $e)
            {
                print(json_encode(array("PHP EXCEPTION : CAN'T DELETE FROM MYSQL. "+$e->getMessage())));
            }
        }else{
            print(json_encode(array("PHP EXCEPTION : CAN'T CONNECT TO MYSQL. NULL CONNECTION.")));
        }
        mysqli_close($con);
    }

}
(d) Index.php

<?php

require_once("/DBAdapter.php");
    $dbAdapter=new DBAdapter();
    $dbAdapter->select();
?>

2. Scripts Gradle

Voici nos scripts gradle dans notre ou nos fichiers build.gradle.

(a). build.gradle(app)

Voici notre fichier build.gradle au niveau de l'application. Nous avons le DSL des dépendances où nous ajoutons nos dépendances.

Ce fichier est appelé app level build.gradle puisqu'il est situé dans le dossier app du projet.

Si vous utilisez Android Studio version 3 et supérieure, utilisez le mot-clé implementation tandis que si vous utilisez une version inférieure à 3, utilisez toujours le mot-clé compile.

Une fois que vous avez modifié ce fichier build.gradle, vous devez synchroniser votre projet. Android Studio vous invitera en effet à le faire.

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    testImplementation 'junit:junit:4.12'
    implementation 'com.android.support:appcompat-v7:24.2.0'
    implementation 'com.android.support:design:24.2.0'
    implementation 'com.android.support:cardview-v7:24.2.0'
    implementation 'com.amitshekhar.android:android-networking:0.2.0'
}

Nous utilisons Fast Android Networking Library comme client HTTP. Vous pouvez utiliser des versions plus récentes.

3. Ressources

La plateforme Android offre un moyen puissant et flexible d'ajouter du contenu statique en tant que ressource.

Ce contenu statique sera également intégré dans le fichier APK. Le contenu statique sera stocké soit comme une ressource, soit comme un actif.

Les ressources appartiennent à un type donné. Ces types peuvent être :

  1. Dessinable.
  2. Mise en page.
  3. Valeur.

Commençons par examiner les ressources de mise en page

(a). model.xml

La mise en page de notre modèle de ligne.

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    android_orientation="horizontal" android_layout_width="match_parent"

    android_layout_margin="10dp"
    card_view_cardCornerRadius="5dp"
    card_view_cardElevation="5dp"
    android_layout_height="200dp">

        <LinearLayout
            android_orientation="vertical"
            android_layout_width="match_parent"
            android_layout_height="match_parent">

            <TextView
                android_layout_width="match_parent"
                android_layout_height="wrap_content"
                android_textAppearance="?android:attr/textAppearanceLarge"
                android_text="Name"
                android_id="@+id/nameTxt"
                android_padding="10dp"
                android_textColor="@color/colorAccent"
                android_textStyle="bold"
                android_layout_alignParentLeft="true"
                />

            <TextView
                android_layout_width="wrap_content"
                android_layout_height="wrap_content"
                android_textAppearance="?android:attr/textAppearanceLarge"
                android_text="Propellant....................."
                android_id="@+id/txtPropellant"
                android_padding="10dp"
                android_layout_alignParentLeft="true"
                />
            <CheckBox
                android_layout_width="wrap_content"
                android_layout_height="wrap_content"
                android_textSize="25dp"
                android_id="@+id/chkTechExists"
                android_checked="true" />

    </LinearLayout>

</androidx.cardview.widget.CardView>
(b). content_main.xml

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

    android_layout_width="match_parent"
    android_layout_height="match_parent"
    android_paddingBottom="@dimen/activity_vertical_margin"
    android_paddingLeft="@dimen/activity_horizontal_margin"
    android_paddingRight="@dimen/activity_horizontal_margin"
    android_paddingTop="@dimen/activity_vertical_margin"
    app_layout_behavior="@string/appbar_scrolling_view_behavior"
    tools_context="com.tutorials.hp.mysqlrecyclerbool.MainActivity"
    tools_showIn="@layout/activity_main">
<!--INPUT VIEWS-->
    <LinearLayout
        android_orientation="vertical"
        android_layout_width="match_parent"
        android_layout_height="wrap_content">

        <android.support.design.widget.TextInputEditText
            android_id="@+id/nameTxt"
            android_hint="Name"
            android_layout_width="match_parent"
            android_layout_height="wrap_content"
            android_textStyle="bold"
            android_textSize="25dp"
            android_enabled="true"
            android_focusable="true" />

        <LinearLayout
            android_orientation="horizontal"
            android_padding="5dp"
            android_layout_width="match_parent"
            android_layout_height="wrap_content">
            <TextView
                android_textSize="25dp"
                android_text="Propellant"
                android_textStyle="bold"
                android_layout_width="250dp"
                android_layout_height="wrap_content" />
            <Spinner
                android_id="@+id/sp"
                android_textSize="25dp"
                android_textStyle="bold"
                android_layout_width="wrap_content"
                android_layout_height="wrap_content" />
        </LinearLayout>

        <LinearLayout
            android_orientation="horizontal"
            android_padding="5dp"
            android_layout_width="match_parent"
            android_layout_height="wrap_content">
            <TextView
                android_textSize="25dp"
                android_text="Technology Exists ??"
                android_textStyle="bold"
                android_layout_width="250dp"
                android_layout_height="wrap_content" />
            <CheckBox
                android_layout_width="wrap_content"
                android_layout_height="wrap_content"
                android_textSize="25dp"
                android_id="@+id/techExists"
                android_checked="true" />
        </LinearLayout>
<!--BUTTONS-->
        <RelativeLayout
            android_orientation="horizontal"
            android_layout_width="match_parent"
            android_layout_height="wrap_content">

            <Button android_id="@+id/addBtn"
                android_layout_width="wrap_content"
                android_layout_height="60dp"
                android_text="Save"
                android_clickable="true"
                android_padding="5dp"
                android_background="#009968"
                android_textColor="@android:color/white"
                android_textStyle="bold"
                android_textSize="20dp" />

            <Button android_id="@+id/refreshBtn"
                android_layout_width="wrap_content"
                android_layout_height="60dp"
                android_text="Retrieve"
                android_padding="5dp"
                android_clickable="true"
                android_background="#f38630"
                android_textColor="@android:color/white"
                android_layout_alignParentTop="true"
                android_layout_alignParentRight="true"
                android_layout_alignParentEnd="true"
                android_textStyle="bold"
                android_textSize="20dp" />

        </RelativeLayout>
<!--RECYCLERVIEW-->
        <androidx.recyclerview.widget.RecyclerView
            android_id="@+id/rv"
            android_layout_width="match_parent"
            android_layout_height="wrap_content">

        </androidx.recyclerview.widget.RecyclerView>

    </LinearLayout>
</RelativeLayout>
(c). activity_main.xml

Ce layout va être gonflé dans l'interface utilisateur de l'activité principale. Cela se fera via la méthode setContentView() de l'activité qui nous demandera de lui passer le layout.

Nous le ferons à l'intérieur de la méthode onCreate() de Activity.

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout

    android_layout_width="match_parent"
    android_layout_height="match_parent"
    android_fitsSystemWindows="true"
    tools_context="com.tutorials.hp.mysqlrecyclerbool.MainActivity">

    <android.support.design.widget.AppBarLayout
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android_id="@+id/toolbar"
            android_layout_width="match_parent"
            android_layout_height="?attr/actionBarSize"
            android_background="?attr/colorPrimary"
            app_popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main" />

    <android.support.design.widget.FloatingActionButton
        android_id="@+id/fab"
        android_layout_width="wrap_content"
        android_layout_height="wrap_content"
        android_layout_gravity="bottom|end"
        android_layout_margin="@dimen/fab_margin"
        android_src="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>

3. Code Java.

Les applications Android peuvent être principalement écrites en Java ou en Kotlin. Ces jours-ci cependant il y a beaucoup de frameworks comme Flutter aussi qui utilisent des langages comme Dart.

Dans ce cours, nous utilisons le langage de programmation Java.

Nous aurons ces classes dans notre projet.

(a). Spacecraft.java

Tout d'abord, nous allons définir les propriétés de notre vaisseau spatial fictif :

package com.tutorials.hp.mysqlrecyclerbool.mModel;

public class Spacecraft {

    /*
    INSTANCE FIELDS
     */
    private int id;
    private String name;
    private String propellant;
    private int technologyExists;

    /*
    GETTERS AND SETTERS
     */
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPropellant() {
        return propellant;
    }

    public void setPropellant(String propellant) {
        this.propellant = propellant;
    }

    public int getTechnologyExists() {
        return technologyExists;
    }

    public void setTechnologyExists(int technologyExists) {
        this.technologyExists = technologyExists;
    }

    /*
    TOSTRING
     */
    @Override
    public String toString() {
        return name;
    }
}

!Structure de la table MySQL](https://github.com/Oclemy/MySQL-Recycler-Boolean/raw/master/demos/TableStructure.PNG)

(b). MySQLClient.java

Nous utilisons la bibliothèque Android Networking Library pour nos appels réseau. Elle le fait en arrière-plan et est facile à utiliser et rapide. Elle nous renverra des réponses JSOn que nous pourrons facilement analyser.

package com.tutorials.hp.mysqlrecyclerbool.mMySQL;

import android.content.Context;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;

import com.androidnetworking.AndroidNetworking;
import com.androidnetworking.common.Priority;
import com.androidnetworking.error.ANError;
import com.androidnetworking.interfaces.JSONArrayRequestListener;
import com.tutorials.hp.mysqlrecyclerbool.mAdapter.MyAdapter;
import com.tutorials.hp.mysqlrecyclerbool.mModel.Spacecraft;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;

public class MySQLClient {

    //SAVE/RETRIEVE URLS
    private static final String DATA_INSERT_URL="http://10.0.2.2/android/Aristotle/crud.php";
    private static final String DATA_RETRIEVE_URL="http://10.0.2.2/android/Aristotle/index.php";

    //INSTANCE FIELDS
    private final Context c;
    private MyAdapter adapter ;

    public MySQLClient(Context c) {
        this.c = c;

    }
    /*
   SAVE/INSERT
    */
    public void add(Spacecraft s, final View...inputViews)
    {
        if(s==null)
        {
            Toast.makeText(c, "No Data To Save", Toast.LENGTH_SHORT).show();
        }
        else
        {
            AndroidNetworking.post(DATA_INSERT_URL)

                    .addBodyParameter("action","save")
                    .addBodyParameter("name",s.getName())
                    .addBodyParameter("propellant",s.getPropellant())
                    .addBodyParameter("technologyexists",String.valueOf(s.getTechnologyExists()))
                    .setTag("TAG_ADD")
                    .build()
                    .getAsJSONArray(new JSONArrayRequestListener() {
                        @Override
                        public void onResponse(JSONArray response) {

                            if(response != null)
                                try {
                                    //SHOW RESPONSE FROM SERVER
                                    String responseString = response.get(0).toString();
                                    Toast.makeText(c, "PHP SERVER RESPONSE : " + responseString, Toast.LENGTH_SHORT).show();

                                    if (responseString.equalsIgnoreCase("Success")) {
                                        //RESET VIEWS
                                        EditText nameTxt = (EditText) inputViews[0];
                                        Spinner spPropellant = (Spinner) inputViews[1];

                                        nameTxt.setText("");
                                        spPropellant.setSelection(0);
                                    }else
                                    {
                                        Toast.makeText(c, "PHP WASN'T SUCCESSFUL. ", Toast.LENGTH_SHORT).show();

                                    }

                                } catch (JSONException e) {
                                    e.printStackTrace();
                                    Toast.makeText(c, "GOOD RESPONSE BUT JAVA CAN'T PARSE JSON IT RECEIVED : "+e.getMessage(), Toast.LENGTH_SHORT).show();
                                }

                        }

                        //ERROR
                        @Override
                        public void onError(ANError anError) {
                            Toast.makeText(c, "UNSUCCESSFUL :  ERROR IS : "+anError.getMessage(), Toast.LENGTH_SHORT).show();
                        }

                    });

        }
    }

    /*
    RETRIEVE/SELECT/REFRESH
     */
    public void retrieve(final RecyclerView rv)
    {
        final ArrayList<Spacecraft> spacecrafts = new ArrayList<>();

        AndroidNetworking.get(DATA_RETRIEVE_URL)
                .setPriority(Priority.HIGH)
                .build()
                .getAsJSONArray(new JSONArrayRequestListener() {
                    @Override
                    public void onResponse(JSONArray response) {
                        JSONObject jo;
                        Spacecraft s;
                        try
                        {
                            for(int i=0;i<response.length();i++)
                            {
                                jo=response.getJSONObject(i);

                                int id=jo.getInt("id");
                                String name=jo.getString("name");
                                String propellant=jo.getString("propellant");
                                String techExists=jo.getString("technologyexists");

                                s=new Spacecraft();
                                s.setId(id);
                                s.setName(name);
                                s.setPropellant(propellant);
                                s.setTechnologyExists(techExists.equalsIgnoreCase("1") ? 1 : 0);

                                spacecrafts.add(s);
                            }

                            //SET TO RECYCLERVIEW
                            adapter =new MyAdapter(c,spacecrafts);
                            rv.setAdapter(adapter);

                        }catch (JSONException e)
                        {
                            Toast.makeText(c, "GOOD RESPONSE BUT JAVA CAN'T PARSE JSON IT RECEIEVED. "+e.getMessage(), Toast.LENGTH_LONG).show();

                        }

                    }

                    //ERROR
                    @Override
                    public void onError(ANError anError) {
                        anError.printStackTrace();
                        Toast.makeText(c, "UNSUCCESSFUL :  ERROR IS : "+anError.getMessage(), Toast.LENGTH_LONG).show();

                    }

                });

    }

}
(c). Mon ViewHolder.java

Notre classe ViewHolder.

package com.tutorials.hp.mysqlrecyclerbool.mAdapter;

import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;

import com.tutorials.hp.mysqlrecyclerbool.R;

public class MyViewHolder extends RecyclerView.ViewHolder {

    TextView txtName,txtPropellant;
    CheckBox chkTechExists;
    public MyViewHolder(View view) {
        super(view);

         txtName = (TextView) view.findViewById(R.id.nameTxt);
         txtPropellant = (TextView) view.findViewById(R.id.txtPropellant);

         chkTechExists = (CheckBox) view.findViewById(R.id.chkTechExists);
    }
}
(d). MonAdaptateur.java

Ci-dessous, notre classe RecyclerView.Adapter.Étant donné que MySQL ne dispose pas d'un type de données booléen natif.Nous allons mapper nos valeurs de cases à cocher booléennes en entiers nullables.

package com.tutorials.hp.mysqlrecyclerbool.mAdapter;

import android.content.Context;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.tutorials.hp.mysqlrecyclerbool.R;
import com.tutorials.hp.mysqlrecyclerbool.mModel.Spacecraft;

import java.util.ArrayList;

public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
    /*
    INSTANCE FIELDS
     */
    private Context c;
    private ArrayList<Spacecraft> spacecrafts;

    /*
    CONSTRUCTOR
     */
    public MyAdapter(Context c, ArrayList<Spacecraft> spacecrafts) {
        this.c = c;
        this.spacecrafts = spacecrafts;
    }

    /*
    INITIALIZE VIEWHOLDER
     */
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v= LayoutInflater.from(c).inflate(R.layout.model,parent,false);
        return new MyViewHolder(v);
    }

    /*
    BIND DATA
     */
    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {

        Spacecraft s=spacecrafts.get(position);

        holder.txtName.setText(s.getName());
        holder.txtPropellant.setText(s.getPropellant());
        holder.chkTechExists.setChecked(s.getTechnologyExists()==1);
    }

    /*
    TOTAL NUM OF SPACECRAFTS
     */
    @Override
    public int getItemCount() {
        return spacecrafts.size();
    }
}
(d). MainActivity.java

C'est notre activité de lancement comme son nom l'indique. Cela signifie qu'elle sera le point d'entrée principal de notre application en ce sens que lorsque l'utilisateur clique sur l'icône de notre application, cette activité sera rendue en premier.

Nous surchargeons une méthode appelée onCreate(). Ici, nous allons commencer par gonfler notre layout principal via la méthode setContentView().

Notre activité principale est en fait une activity puisqu'elle dérive de l'AppCompatActivity.

package com.tutorials.hp.mysqlrecyclerbool;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.TextInputEditText;
import androidx.appcompat.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.Spinner;
import android.widget.Toast;

import com.tutorials.hp.mysqlrecyclerbool.mAdapter.MyAdapter;
import com.tutorials.hp.mysqlrecyclerbool.mModel.Spacecraft;
import com.tutorials.hp.mysqlrecyclerbool.mMySQL.MySQLClient;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    //INSTANCE FIELDS
    private TextInputEditText txtName;
    private CheckBox chkTechnologyExists;
    private Spinner spPropellant;
    private RecyclerView rv;
    private Button btnAdd,btnRetrieve;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        //REFERENCE VIEWS
        this.initializeViews();

        populatePropellants();

        //HANDLE EVENTS
        this.handleClickEvents();

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                rv.setAdapter(new MyAdapter(MainActivity.this,new ArrayList<Spacecraft>()));
            }
        });

    }

    /*
    REFERENCE VIEWS
     */
    private void initializeViews()
    {

        txtName= (TextInputEditText) findViewById(R.id.nameTxt);
        chkTechnologyExists= (CheckBox) findViewById(R.id.techExists);
        spPropellant= (Spinner) findViewById(R.id.sp);
        rv= (RecyclerView) findViewById(R.id.rv);

        btnAdd= (Button) findViewById(R.id.addBtn);
        btnRetrieve= (Button) findViewById(R.id.refreshBtn);

        rv.setLayoutManager(new LinearLayoutManager(MainActivity.this));

    }

    /*
    HANDLE CLICK EVENTS
     */
    private void handleClickEvents()
    {
        //EVENTS : ADD
        btnAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                //GET VALUES
                String name=txtName.getText().toString();
                String propellant=spPropellant.getSelectedItem().toString();
                Boolean technologyexists=chkTechnologyExists.isChecked();

                //BASIC CLIENT SIDE VALIDATION
                if((name.length()<1 || propellant.length()<1  ))
                {
                    Toast.makeText(MainActivity.this, "Please Enter all Fields", Toast.LENGTH_SHORT).show();
                }
                else
                {
                    //SAVE

                    Spacecraft s=new Spacecraft();
                    s.setName(name);
                    s.setPropellant(propellant);
                    s.setTechnologyExists(technologyexists ? 1 : 0);

                    new MySQLClient(MainActivity.this).add(s,txtName,spPropellant);
                }
            }
        });

        //EVENTS : RETRIEVE
        btnRetrieve.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new MySQLClient(MainActivity.this).retrieve(rv);

            }
        });

    }

    private void populatePropellants()
    {
        ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,android.R.layout.simple_spinner_dropdown_item);

        adapter.add("None");
        adapter.add("Chemical Energy");
        adapter.add("Nuclear Energy");
        adapter.add("Laser Beam");
        adapter.add("Anti-Matter");
        adapter.add("Plasma Ions");
        adapter.add("Warp Drive");

        spPropellant.setAdapter(adapter);
        spPropellant.setSelection(0);

    }
}

AndroidManifest.xml

Assurez-vous d'ajouter la permission pour la connectivité internet.

<?xml version="1.0" encoding="utf-8"?>
<manifest
    package="com.tutorials.hp.mysqlrecyclerbool">

    <uses-permission android_name="android.permission.INTERNET"/>

    <application
        android_allowBackup="true"
        android_icon="@mipmap/ic_launcher"
        android_label="@string/app_name"
        android_supportsRtl="true"
        android_theme="@style/AppTheme">
        <activity
            android_name=".MainActivity"
            android_label="@string/app_name"
            android_theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android_name="android.intent.action.MAIN" />

                <category android_name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Télécharger

Hey,tout est dans le code source de référence qui est bien commenté et facile à comprendre et peut être téléchargé ci-dessous.

Vérifiez également notre tutoriel vidéo c'est plus détaillé et expliqué en étape par étape.

No. Location Link
1. GitHub Direct Download
2. GitHub Browse
3. YouTube Video Tutorial

Catégorisé: