Android RecyclerView mit RadioButton oder CheckBox – Beispiele
In diesem Tutorial werden wir uns die Erstellung und Verwendung einer benutzerdefinierten RecyclerView mit Checkboxen oder Radiobuttons ansehen und wie man ihre Zustände behandelt.
Konzepte, die Sie lernen werden
Dieses Tutorial soll Ihnen anhand von Beispielen helfen, das Folgende zu lernen:
- Wie man eine Recyclerview mit Checkboxen oder Radiobuttons erstellt und wie man ihre Zustände richtig handhabt.
- Wie man Daten aus einer Mysql-Datenbank, einschließlich boolescher Daten, in einem Recyclerview mit Checkboxen darstellt.
- Wie man Recyclerviews mit Checkboxen durchsucht/filtert und dabei deren Status beibehält (markiert/deaktiviert).
Demos
Hier sind einige der Demos, die wir erstellen werden:
CheckBox Demo

RadioButton Demo

Beispiel 1: Android RecyclerView CheckBoxes - Maintain Checked States
Dies ist ein Android RecyclerView Checkboxes Tutorial. Wir wollen sehen, wie man zuerst Checkboxen, Bilder und Text in einem benutzerdefinierten RecyclerView mit Cardviews rendert. Dann werden die ausgewählten oder angekreuzten Kartenansichten mit einer Toast-Nachricht angezeigt. Wir arbeiten mit mehreren Kontrollkästchen, so dass wir Elemente in unserer RecyclerView mehrfach oder einzeln auswählen können.
So lernen wir, wie wir den angekreuzten Status unserer Checkboxen in unserer RecyclerView trotz des Recyclings unserer Cardviews mit Checkboxen beibehalten können.
Dann kann der Benutzer auf eine schwebende Aktionsschaltfläche klicken, um die ausgewählten Elemente zu erhalten und in einer Toast-Nachricht anzuzeigen.
Wir bauen eine lebendige YouTube-Community auf
Hier ist dieses Tutorial im Video Format.
Schritt 1: Abhängigkeiten
Für dieses Projekt benötigen wir keine speziellen Abhängigkeiten. Alles was wir verwenden sind die Standard androidx Abhängigkeiten wie recyclerview und cardview.
Schritt 2: Erstellen des Hauptlayouts der Aktivität
activity_main.xml
Dies wird unser Hauptaktivitätslayout sein und wir schreiben es in XML. XML ist eine Auszeichnungssprache, die nicht nur für die Erstellung von Benutzeroberflächen, sondern auch für die Ausgabe von Daten verwendet wird, in diesem Fall für die Erstellung unserer Android-Benutzeroberfläche.
Dieses Layout wird in unsere Hauptaktivität eingefügt. An der Wurzel haben wir ein RelativeLayout.
Wir haben eine TextView, die unsere headerTextView ist, um die Überschrift unserer Android-Anwendung anzuzeigen.
Dann haben wir eine RecyclerView, die in diesem Fall unsere Adapterview ist. Diese RecyclerView wird Bilder, Text und Checkboxen darstellen.
Unterhalb der RecyclerView befindet sich ein FloatingActionButton. Wenn der Benutzer auf diesen FAB-Button klickt, werden wir die ausgewählten Elemente in der RecyclerView anzeigen. Denken Sie daran, dass unser RecyclerView aus Cardviews besteht, die Bilder, Text und Checkboxen enthalten.
<?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>
Schritt 3: Erstellen eines RecyclerView Elements
model.xml
Dieses Layout wird eine einzelne Kartenansicht modellieren, die zwischen anderen Karten in unserer RecyclerView gerendert wird.
Dieses Layout wird alle diese Kartenansichten modellieren. An der Wurzel haben wir die CardView als unser Element. CardView befindet sich im Namespace "android.support.v7.widget".
Ich habe die Kartenhöhe auf 5dp und den Kartenradius auf 10dp eingestellt.
Innerhalb der Karte habe ich ein RelativeLayout, um meine Widgets relativ zueinander zu organisieren.
Zuerst haben wir die ImageView, um unser Bild darzustellen. Dann TextViews, um unsere Texte darzustellen.
Ganz rechts von unserer CardView werden wir eine CheckBox haben, die die Auswahleigenschaft jeder CardView enthält. Die CheckBoxen können angekreuzt oder nicht angekreuzt werden.
<?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>
Schritt 4: MainActivity.java
Paket angeben und Importe hinzufügen
Unsere Java-Klasse wird sich in einem Paket befinden, also geben wir eines an und fügen die entsprechenden Importe hinzu.
Dazu gehören unser RecyclerView aus dem Paket android.support.v7.widget und CheckBox aus dem Paket 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;
Activity erstellen
Eine Activity ist eine Android-Komponente, die eine Benutzeroberfläche darstellt.
Um unsere gewöhnliche Klasse in eine Activity zu verwandeln, werden wir sie von AppCompatActivity ableiten lassen:
public class MainActivity extends AppCompatActivity {..}
Erstellen Sie unser POJO
Dann werden wir eine POJO-Klasse erstellen, Plain OLd Java Object. Diese wird ein einzelnes Teacher-Objekt repräsentieren.
Jeder SpiritualTecaher wird mehrere Eigenschaften haben. Jedes Objekt wird in seiner eigenen CardView in unserer RecyclerView dargestellt.
public class SpiritualTeacher {
//our properties.
}
Eine dieser Eigenschaften wird die Eigenschaft "isSelected" sein, ein boolescher Wert, der für uns den überprüften Status unserer CardView enthält.
Erstellen Sie unseren View Holder
Wir werden unsere RecyclerView ViewHolder Klasse erstellen, indem wir von der RecyclerView.ViewHolder Klasse ableiten.
Außerdem wird die Klasse die Schnittstelle "View.OnClickListener" implementieren. Dies wird uns erlauben, Klick-Ereignisse unserer einzelnen CardViews zu erfassen.
static class MyHolder extends RecyclerView.ViewHolder implements View.OnClickListener{...}
RecyclerView Adapter erstellen
Dann erstellen wir unsere RecyclerView.Adapter Klasse, die Klasse, die unsere Adapterklasse sein wird.
static class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder> {..}
Als Adapterklasse hat diese Klasse zwei Hauptaufgaben:
- Unser Custom Model Layout in ein View Object aufblasen.
- Binden von Datensätzen an unsere aufgeblasenen Views.
Die zu bindenden Daten werden aus einem benutzerdefinierten Array kommen, in diesem Fall ein Array von SpiritualTeachers:
public MyAdapter(Context c, SpiritualTeacher[] teachers) {
this.c = c;
this.teachers = teachers;
}
Diese Klasse wird auch eine Arrayliste verwalten, die unsere geprüften Elemente enthält.
ArrayList<SpiritualTeacher> checkedTeachers=new ArrayList<>();
Die Benutzer werden die Recyclerview-Elemente prüfen und wir halten diese geprüften Elemente in dieser Array-Liste. Später können wir dann diese geprüften Elemente in einer Toast-Nachricht anzeigen.
Layout in Ansicht aufblasen
Dies wird in unserem RecyclerView Adapter stattfinden, wie wir vereinbart haben. Dazu benötigen wir eine LayoutInflater Klasse.
@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;
}
Wie man sehen kann, haben wir das inflate view Objekt an unseren RecyclerView ViewHolder Konstruktor übergeben.
Dann wird die View Holder Instanz zurückgegeben.
Daten binden
Wir binden Daten innerhalb der onBindViewHolder Methode:
@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());
...
}
Zuerst haben wir die Position des Elements in unserem Recyclerview erhalten und sie benutzt, um den aktuellen Lehrer aus unserem Array zu holen.
Dann setzen wir die Widgets TextView, imageView und CheckBox mit Werten aus diesem Objekt.
Geprüfte und nicht geprüfte Elemente beibehalten
Dann hören wir auf Klick-Ereignisse in unserer CardView. Es ist offensichtlich, dass ein Klick auf die CheckBox den Status dieser CheckBox ändert.
Wir prüfen auf diese Änderungen. Wenn das Kontrollkästchen angeklickt wird, fügen wir das Element in unsere Arrayliste ein.
Wenn es nicht angeklickt ist, entfernen wir das Element aus der Arrayliste.
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);
}
}
});
Schauen wir uns den vollständigen Quellcode an.
Vollständiger Code
Hier ist der vollständige Code von 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);
}
}
Beispiel 2: SingleChoice RecyclerView - mit RadioButtons
Android SingleChoice RecyclerView Tutorial
In diesem Tutorial wollen wir sehen, wie man eine SingleChoice RecyclerView erstellt. Das ist ein Recyclerview mit
Radiobuttons. Der Benutzer kann ein einzelnes Element auswählen und wir öffnen die Detailaktivität des Elements und zeigen dessen Daten an.
Warum SingleChoice RecyclerView?
Nun, die Alternative ist ein Multi-Choice RecyclerView, also ein RecyclerView mit Checkboxen. Aber in manchen Fällen
möchte man, dass der Benutzer nur ein einziges Element aus der RecyclerView auswählen kann. Hier kommen die Radiobuttons ins Spiel.
In unserem Fall werden wir jedoch eine Detailaktivität öffnen, wenn der Benutzer einen bestimmten Radiobutton auswählt. Dann verwenden wir Intents, um
Daten an die Detailaktivität zu übergeben.
Was zeigen wir?
Nun, wir zeigen Bilder, Text und Radiobuttons. Normalerweise werden Bilder in imageview gerendert. Der Text
wird in der Textansicht gerendert. Auf der anderen Seite zeigen die Radiobuttons
einen zusammengesetzten Status anzeigen, also ob sie aktiviert sind oder nicht.
Schritt 1: Gradle-Skripte
(a) Build.gradle
Es ist keine besondere Abhängigkeit erforderlich. Wir fügen CardView und recyclerview als unsere Abhängigkeiten hinzu.
Die CardView wird unsere Galaxy-Objekte enthalten. Die RecyclerView wird mehrere Cardviews enthalten. AppCompat wird uns die
AppCompatActivity, von der unsere MainActivity ausgeht.
Schritt 2: Layouts erstellen
Wir haben drei Layouts
1. activity_main.xml
Dieses Layout wird in MainActivity aufgeblasen. Es enthält einfach unsere RecyclerView. Ich habe meinem Layout eine eigene
Hintergrundfarbe gegeben.
<?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. activity_detail.xml
Das Layout für unsere Detail-Aktivität. Enthält imageview und textviews.to show
unsere Daten.
<?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
Dies ist unser Layout für die Elementansicht. Es wird in die Elemente unserer RecyclerView-Ansicht aufgeblasen. Dies wird von unserem RecyclerView
Adapter.
<?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>
Schritt 4: Java Code schreiben.
Wir haben die folgenden Java-Klassen für dieses Projekt:
- Galaxy.java
- RecyclerAdapter.java
- DetailsActivity.java
- MainActivity.java
(a).Galaxy.java
Dies wird unser Datenobjekt darstellen. Es ist unsere Modellklasse und repräsentiert eine Galaxie mit Eigenschaften wie:
- Name.
- Beschreibung
- Bild.
Hier ist der vollständige Code.
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;}
}
Sie können sehen, dass wir die Schnittstelle Serializable implementiert haben. Dies erlaubt uns, unser Datenobjekt zu serialisieren, so dass
damit es per Intent an die DetailsActivity-Aktivität als Ganzes transportiert werden kann.
(b). RecyclerAdapter.java
Dies ist unsere Adapterklasse. Sie wird unser Modell-Layout in ein View-Objekt aufblasen, das von der Recyclerview gerendert werden kann.
Sie wird auch Daten an diese aufgeblasenen View-Objekte binden.
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
Unsere Detail-Activity-Klasse. Diese zeigt die Details der angeklickten Galaxie an.
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
Unsere Hauptaktivitätsklasse. Hier referenzieren wir unsere Recyclerview und definieren unsere Datenquelle.
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);
}
}
Herunterladen
Sie können den vollständigen Quellcode unten herunterladen oder sich das Video über den angegebenen Link ansehen.
| --- |
|---|
Beispiel 3: Kotlin Android RecyclerView - CardView mit CheckBox,Images,Text und ItemClick
Kotlin Android RecyclerView mit CheckBoxen, Bildern, Text und ItemClick unterstützt Tutorial und Beispiel.
In diesem Tutorial möchte ich zeigen, wie man mit der RecyclerView arbeiten kann und wie man sie mit Checkboxen, Bildern, Text und Click-Events verwenden kann. All das machen wir in einer einzigen MainActivity.kt Datei.
Video-Tutorial
Wenn Sie ein Video-Tutorial bevorzugen, schauen Sie hier:
Was Sie lernen
Hier sind die Konzepte, die Sie lernen:
- Wie man Recyclerview in Android mit der Programmiersprache Kotlin verwendet.
- Wie man CheckBoxen mit Recyclerview verwendet und die Zustände der Checkboxen angemessen behandelt.
- Wie man eine Recyclerview mit Bildern und Text erstellt.
- Wie man das Element-Klick-Ereignis in Recyclerview unterstützt.
Verwendete Tools
Hier sind die Werkzeuge, die ich für dieses Projekt verwendet habe:
- Programmiersprache: Kotlin
- Rahmenwerk - Android
- IDE - Android Studio.
- Emulator - Nox Player
- OS : Windows 8.1
Fangen wir an.
Demo
Hier ist die Demo für dieses Projekt:

(a). Build.gradle
Unsere App-Ebene build.gradle.
Hier fügen wir unsere Abhängigkeiten hinzu. Insbesondere sind wir an drei davon interessiert:
- AppCompat - Um uns die AppCompatActivity zu geben, von der unsere
MainActivityabgeleitet wird. - Design Support - Um uns die RecyclerView zu geben.
- CardView - Um uns Cardview zu geben.
(b). activity_main.xml
Dies ist unser Hauptlayout für die Aktivität. Hier sind die Komponenten, die wir verwenden:
- RelativeLayout - Um unsere anderen Widgets relativ zueinander anzuordnen.
- TextView - Zur Darstellung von Kopfzeilentext.
- RecyclerView - Um unsere Daten darzustellen.
- Floating Action Button - Um die angekreuzten Elemente anzuzeigen, wenn sie angeklickt werden.
<?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
Dieses Layout wird unsere Elementansichten für unsere Recycleransicht definieren, es wird sie modellieren. Im Grunde genommen wird es Daten für ein einzelnes SpiritualTeacher Objekt darstellen. An der Wurzel haben wir eine CardView. Dann haben wir auch:
- ImageView - Um Bilder für das
SpiritualTeacherObjekt darzustellen. - TextVIew - Um seinen Namen und seine Beschreibung darzustellen.
- CheckBox - Damit wir die CardViews auswählen und abwählen können.
<?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
Dies ist unsere Haupt-[Aktivität] (https://camposha.info/android/activity). Dies ist unsere einzige Datei und wir werden hier mehrere innere Kotlin-Klassen definieren. Diese Klasse wird von der AppCompatActivity abgeleitet.
Datenobjekt erstellen
Wir beginnen mit der Definition einer inneren Klasse namens SpiritualTeacher:
inner class SpiritualTeacher(var name: String?, val quote: String, val image: Int) {
var isSelected: Boolean = false
}
Diese Klasse ist unser Datenobjekt. Sie wird ihre Parameter über den Konstruktor erhalten. Außerdem verwalten wir einen einfachen Booleschen Wert, der uns den Auswahlstatus der CardViews liefert. In der Tat ist dies die Magie, die es uns erlaubt, unsere Elemente in unserer Recyclerview zu selektieren und zu deselektieren. Auf diese Weise verliert unser Recyclerview nicht den Status, selbst wenn wir scrollen und die Elemente des Recyclerviews recycelt werden. Das liegt daran, dass wir sie als Daten in unserem Objekt halten und sie vom Recycling nicht betroffen sind.
RecyclerVew Adapter Klasse erstellen
Normalerweise hat der Adapter zwei Hauptaufgaben. Erstens das Aufblasen unserer benutzerdefinierten Layouts und zweitens das Binden von Daten an die resultierenden Widgets. Recyclerview geht jedoch noch weiter, indem es uns erlaubt, Elemente zu recyceln. Dies spart Speicherplatz, da das Aufblasen ein teurer Prozess ist und sich negativ auf unsere Anwendung auswirken würde, wenn wir dies für jedes Element in der Recycle-Ansicht tun würden.
Wir werden also einen Adapter erstellen:
internal class MyAdapter(var c: Context, var teachers: Array<SpiritualTeacher>) : RecyclerView.Adapter<MyAdapter.MyHolder>() {..}
Wir haben ihn von der Klasse "RecyclerView.Adapter" abgeleitet.
Innerhalb des Adapters werden wir zuerst eine Arrayliste erstellen, die für uns die Lehrer, die überprüft wurden, enthalten wird:
var checkedTeachers = ArrayList<SpiritualTeacher>()
Innerhalb der Methode onCreateViewHolder() werden wir unser model.xml in ein View-Objekt aufblasen. Dazu verwenden wir die Klasse LayoutInflater.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.model, null)
return MyHolder(v)
}
Hier ist der vollständige Quellcode.
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
}
Beispiel 4: Android MySQL - RecyclerView CheckBoxes - INSERT,SELECT,SHOW
*Dies ist ein Android-Mysql-RecyclerView mit Checkboxen-Tutorial. Wir sehen, wie wir mit unserer mysql-Datenbank sowohl mit Text- als auch mit booleschen Werten arbeiten können.
- Heute untersuchen wir, wie man mit booleschen und Textwerten mit MySQL und RecyclerView arbeitet.
- Zuerst fügen wir Daten in die MySQL-Datenbank ein.
- Die Komponenten, die wir als Eingabeansichten verwenden, sind chcekbox, spinner und material edittext.
- Der Benutzer tippt den Namen seines bevorzugten Raumschiffs in den Edittext und wählt dann den Treibstoff dieses Raumschiffs in einem Spinner aus.
- Dann aktiviert/deaktiviert er ein Kontrollkästchen, um festzustellen, ob diese Technologie bereits existiert oder nicht.
- Wir speichern diese Daten auf Knopfdruck in MySQL.
- Beim Klick auf die Schaltfläche "Abrufen" wählen wir die Daten aus MySQL aus und binden diesen Text und Booleschen Wert an unsere Checked RecyclerView, RecyclerView mit CheckBoxen.
Zunächst möchte ich sagen, dass wir den vollständigen, gut kommentierten Quellcode oben zum Download als vollständige Referenz haben. Wir haben die PHP-Datei, die wir verwendet haben, eingeschlossen. Sie werden es in Ihrem Server-Root-Verzeichnis platzieren und Dinge wie Benutzername, Tabellenname usw. ändern.
Video-Tutorial (ProgrammingWizards TV Channel)
Nun, wir haben ein Video-Tutorial als Alternative zu dieser Anleitung. Wenn Sie Tutorials wie dieses bevorzugen, dann wäre es gut, wenn Sie unseren YouTube-Kanal abonnieren.
Im Grunde haben wir ein TV für die Programmierung, wo wir täglich Tutorials speziell für Android zeigen.
Android MySQL RecyclerView CheckBoxes Insert, Select Show Beispiel
Schauen wir uns unser Beispiel an:
MySQL-Tabelle
Hier ist die Struktur unserer MySQL-Tabelle:
Projekt-Struktur
Hier ist unsere Projektstruktur.
1. PHP-Code
Hier ist unser PHP-Code:
(a) Konstanten.php
Unsere PHP-Klasse, die Datenbankkonstanten wie Servername, Datenbankname, Benutzername und Passwort enthält. Diese Zugangsdaten werden benötigt, um eine Verbindung zur MySQL-Datenbank herzustellen.
<?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
Diese PHP-Datei ermöglicht es uns, Daten von HTTP-Clients zu empfangen, indem sie auf Anfragen hört und diese bearbeitet. Wir behandeln diese Anfragen, indem wir die in unserer Klasse DBAdapater.php definierten CRUD-Aktionen einleiten.
<?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
Diese PHP-Datei enthält Funktionen, mit denen wir CRUD-Operationen in unserer MySQL-Datenbank durchführen können. Solche Aktionen beinhalten das Einfügen und Abrufen von Daten in und aus der Datenbank.
<?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. Gradle-Skripte
Hier sind unsere Gradle-Skripte in unserer/unseren build.gradle-Datei(en).
(a). build.gradle(app)
Hier ist unsere Anwendungsebenebuild.gradle Datei. Wir haben die Dependencies-DSL, in der wir unsere Abhängigkeiten hinzufügen.
Diese Datei wird app level build.gradle genannt, da sie sich im app Ordner des Projekts befindet.
Wenn Sie Android Studio Version 3 und höher verwenden, benutzen Sie das Schlüsselwort implementation, wenn Sie eine Version unter 3 verwenden, benutzen Sie das Schlüsselwort compile.
Sobald Sie diese Datei build.gradle geändert haben, müssen Sie Ihr Projekt synchronisieren. Android Studio wird Sie tatsächlich dazu auffordern.
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'
}
Wir verwenden die Fast Android Networking Library als unseren HTTP-Client. Sie können auch neuere Versionen verwenden.
3. Resoourcen
Die Android-Plattform bietet eine leistungsstarke und flexible Möglichkeit, statische Inhalte als Ressource hinzuzufügen.
Diese statischen Inhalte werden auch in die APK-Datei verpackt. Der statische Inhalt wird entweder als Ressource oder als Asset gespeichert.
Ressourcen gehören zu einem bestimmten Typ. Diese Typen können sein:
- Zeichnungsfähig.
- Layout.
- Wert.
Beginnen wir mit der Betrachtung der Layout-Ressourcen
(a). model.xml
Unser Zeilenmodell-Layout.
<?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
Dieses Layout wird in die Benutzeroberfläche der Hauptaktivität aufgeblasen. Dies geschieht über die Methode setContentView() der Activity, die es erfordert, dass wir ihr das Layout übergeben.
Wir werden dies innerhalb der onCreate() Methode von Activity tun.
<?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. Java-Code.
Android-Apps können hauptsächlich in Java oder Kotlin geschrieben werden. Heutzutage gibt es jedoch viele Frameworks wie Flutter, die auch Sprachen wie Dart verwenden.
In diesem Kurs verwenden wir die Programmiersprache Java.
Wir werden diese Klassen in unserem Projekt verwenden.
(a). Raumschiff.java
Lassen Sie uns zunächst die Eigenschaften unseres fiktiven Raumschiffs definieren:
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;
}
}
(b). MySQLClient.java
Wir verwenden die Android Networking Library für unsere Netzwerkaufrufe, die im Hintergrund abläuft und einfach und schnell zu bedienen ist und uns JSOn-Antworten zurückgibt, die wir leicht analysieren können.
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). MyViewHolder.java
Unsere ViewHolder-Klasse.
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). MyAdapter.java
Unten ist unsere RecyclerView.Adapter Klasse.Da MySQL keinen nativen booleschen Datentyp hat, werden wir unsere booleschen Checkboxwerte auf nullbare Integerwerte abbilden.
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
Dies ist, wie der Name schon sagt, unsere Startaktivität. Das bedeutet, dass sie der Haupteinstiegspunkt in unsere Anwendung sein wird, denn wenn der Benutzer auf das Symbol für unsere Anwendung klickt, wird diese Aktivität zuerst gerendert.
Wir überschreiben eine Methode namens onCreate(). Hier beginnen wir mit dem Aufblasen unseres Hauptlayouts über die Methode setContentView().
Unsere Hauptaktivität ist eigentlich eine activity, da sie von der AppCompatActivity abgeleitet ist.
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
Stellen Sie sicher, dass Sie die Berechtigung für die Internetverbindung hinzufügen.
<?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>
Herunterladen
Hey, alles ist in Quellcode-Referenz, die gut kommentiert und leicht zu verstehen ist und kann unten heruntergeladen werden.
Schauen Sie sich auch unser Video-Tutorial an, das detaillierter ist und Schritt für Schritt erklärt wird.
| --- |
|---|