Android RecyclerView und Android CardView wurden in Android Lollipop mit Material Design eingeführt. Für diejenigen, die sich nicht mit Material Design auskennen, handelt es sich um einen umfassenden Leitfaden für UI-Widgets, der seit Android 5.0 eingeführt wurde und die visuelle Anziehungskraft von Apps verbessert.
Android RecyclerView
Android RecyclerView ist eine fortschrittlichere, leistungsstärkere und flexiblere Version der ListView. Android RecyclerView ähnelt der ListView, mit der Ausnahme, dass sie uns dazu zwingt, die RecyclerView.ViewHolder-Klasse zum Halten der Elemente zu verwenden, was bei ListView nicht zwingend erforderlich ist. Wie der Name schon sagt, wird Android RecyclerView verwendet, um Zellen beim Scrollen nach oben und unten wiederzuverwenden, indem die Elemente in der Liste recycelt werden. Eine weitere Verbesserung in RecyclerView ist, dass es uns erlaubt, die LayoutManagers dynamisch zur Laufzeit festzulegen, im Gegensatz zur ListView, die nur in einer vertikalen Bildlaufliste verfügbar war. RecyclerView ermöglicht es uns, die folgenden Arten von Layouts zur Laufzeit festzulegen.
- LinearLayoutManager: Es unterstützt sowohl vertikale als auch horizontale Listen.
- StaggeredLayoutManager : Es unterstützt gestaffelte Listen
- GridLayoutManager : Es unterstützt die Anzeige von Rastern wie im früheren GalleryView
Android RecyclerView-Klassen
- Die Klasse RecyclerView.ItemAnimator bietet bessere Unterstützung zum Animieren der Ansichten im Vergleich zu den ListViews
- Die Klasse RecyclerView.ItemDecorator bietet bessere Unterstützung beim Hinzufügen von Rahmen und Trennlinien und gibt uns dadurch eine enorme Kontrolle
Daher ist ein RecyclerView im Vergleich zu ListView anpassbarer und gibt den Benutzern mehr Kontrolle. Der RecyclerView ist in der Support-Bibliothek verfügbar. Daher müssen wir unser Gradle-Skript ändern, um die folgende Abhängigkeit hinzuzufügen.
dependencies {
compile 'com.android.support:recyclerview-v7:21.0.0-rc1'
}
Android CardView
Das Android CardView-Benutzeroberflächenkomponente zeigt Informationen in Karten an. Diese Komponente wird im Allgemeinen verwendet, um Kontaktinformationen anzuzeigen. Diese Komponente ist in einer anderen Support-Bibliothek verfügbar, daher müssen wir auch ihre Abhängigkeit hinzufügen.
dependencies {
compile 'com.android.support:cardview-v7:21.0.0-rc1'
compile 'com.android.support:recyclerview-v7:21.0.0-rc1'
}
Android CardView-Widget ermöglicht es uns, Hintergrundfarbe, Schatten, Eckenradius, Höhe usw. zu steuern. Um die benutzerdefinierten Attribute in XML zu verwenden, müssen wir der übergeordneten Layoutdatei die folgende Namensraumdeklaration hinzufügen. Hier ist die Namensraumdeklaration mit einigen Attributen aus unserem Projekt.
<android.support.v7.widget.CardView
android:id="@+id/card_view"
xmlns:card_view="https://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardBackgroundColor="@color/grey_300"
card_view:cardCornerRadius="10dp"
card_view:cardElevation="5dp"
card_view:cardUseCompatPadding="true">
Die wichtigsten oben verwendeten Attribute sind:
- card_view:cardCornerRadius: Wird verwendet, um den Eckenradius in unseren Layouts festzulegen
- card_view:cardBackgroundColor: Wird verwendet, um die Hintergrundfarbe der Ansicht festzulegen
In unserem Beispielprojekt fügen wir einen RecyclerView hinzu, um eine Liste von CardViews anzuzeigen, die Android-Versionen und Nummern sowie ein Beispiellogo enthalten. Das CardView-onclick
ist programmiert, um diese Karte aus der Liste zu entfernen. Wir haben eine Menüoption in der ActionBar hinzugefügt, um die entfernten Karten in aufeinanderfolgender Reihenfolge zurückzusetzen. Hinweis: Die Logo-Bilder werden zufällig von Google ausgewählt. Daher können die Größen variieren.
Beispiel für Android RecyclerView und CardView
Das Projekt besteht aus einer
MainActivity
, die das RecyclerView
anzeigt. Die CardView wird der RecyclerView aus der CustomAdapter-Klasse hinzugefügt. Das DataModel wird verwendet, um die Daten für jede CardView über Getter abzurufen. Die MyData-Klasse enthält die Arrays von Textviews und Drawables sowie deren IDs.
Android RecyclerView und CardView Beispielcode
Die activity_main.xml
enthält den RecyclerView in einem RelativeLayout wie unten dargestellt. activity_main.xml Code:
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity"
android:background="@color/grey_300"
>
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
/>
</RelativeLayout>
Das Layout für Android CardView ist unten definiert: cards_layout.xml Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:tag="cards main container">
<android.support.v7.widget.CardView
android:id="@+id/card_view"
xmlns:card_view="https://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardBackgroundColor="@color/color_white"
card_view:cardCornerRadius="10dp"
card_view:cardElevation="5dp"
card_view:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<ImageView
android:id="@+id/imageView"
android:tag="image_tag"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_weight="1"
android:src="@drawable/ic_launcher"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_weight="2"
android:orientation="vertical"
>
<TextView
android:id="@+id/textViewName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:text="Android Name"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<TextView
android:id="@+id/textViewVersion"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:text="Android Version"
android:textAppearance="?android:attr/textAppearanceMedium"/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
Die Android CardView enthält ein ImageView sowie zwei TextViews in einem verschachtelten Linear Layout. Die menu_main.xml
enthält ein einzelnes Element, um die entfernten Karten zurückzusetzen. menu_main.xml Code:
<menu xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
tools:context=".MainActivity">
<item android:id="@+id/add_item"
android:title="Add"
android:orderInCategory="100"
app:showAsAction="always"/>
</menu>
Die Klasse MainActivity.java
ist unten definiert:
package com.journaldev.recyclerviewcardview;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private static RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
private static RecyclerView recyclerView;
private static ArrayList data;
static View.OnClickListener myOnClickListener;
private static ArrayList removedItems;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myOnClickListener = new MyOnClickListener(this);
recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
data = new ArrayList();
for (int i = 0; i < MyData.nameArray.length; i++) {
data.add(new DataModel(
MyData.nameArray[i],
MyData.versionArray[i],
MyData.id_[i],
MyData.drawableArray[i]
));
}
removedItems = new ArrayList();
adapter = new CustomAdapter(data);
recyclerView.setAdapter(adapter);
}
private static class MyOnClickListener implements View.OnClickListener {
private final Context context;
private MyOnClickListener(Context context) {
this.context = context;
}
@Override
public void onClick(View v) {
removeItem(v);
}
private void removeItem(View v) {
int selectedItemPosition = recyclerView.getChildPosition(v);
RecyclerView.ViewHolder viewHolder
= recyclerView.findViewHolderForPosition(selectedItemPosition);
TextView textViewName
= (TextView) viewHolder.itemView.findViewById(R.id.textViewName);
String selectedName = (String) textViewName.getText();
int selectedItemId = -1;
for (int i = 0; i < MyData.nameArray.length; i++) {
if (selectedName.equals(MyData.nameArray[i])) {
selectedItemId = MyData.id_[i];
}
}
removedItems.add(selectedItemId);
data.remove(selectedItemPosition);
adapter.notifyItemRemoved(selectedItemPosition);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
if (item.getItemId() == R.id.add_item) {
// Überprüfen, ob Elemente hinzuzufügen sind
if (removedItems.size() != 0) {
addRemovedItemToList();
} else {
Toast.makeText(this, "Nothing to add", Toast.LENGTH_SHORT).show();
}
}
return true;
}
private void addRemovedItemToList() {
int addItemAtListPosition = 3;
data.add(addItemAtListPosition, new DataModel(
MyData.nameArray[removedItems.get(0)],
MyData.versionArray[removedItems.get(0)],
MyData.id_[removedItems.get(0)],
MyData.drawableArray[removedItems.get(0)]
));
adapter.notifyItemInserted(addItemAtListPosition);
removedItems.remove(0);
}
}
Die removeItems()
-Methode wird aus der Listener-Methode aufgerufen, um den angeklickten CardView zu entfernen. Seine entsprechende ID wird in einem Array gespeichert, um später darauf zugreifen zu können. Um die Ansicht später hinzuzufügen, haben wir eine weitere Methode namens addRemovedItemToList()
implementiert. In dieser Methode fügen wir die Ansicht an einer vordefinierten Position in der Liste hinzu und entfernen ihre ID aus dem removedItems
-Array. Der CustomAdapter wird in beiden Fällen benachrichtigt. Die Klasse CustomeAdapter.java ist unten definiert:
package com.journaldev.recyclerviewcardview;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> {
private ArrayList<DataModel> dataSet;
public static class MyViewHolder extends RecyclerView.ViewHolder {
TextView textViewName;
TextView textViewVersion;
ImageView imageViewIcon;
public MyViewHolder(View itemView) {
super(itemView);
this.textViewName = (TextView) itemView.findViewById(R.id.textViewName);
this.textViewVersion = (TextView) itemView.findViewById(R.id.textViewVersion);
this.imageViewIcon = (ImageView) itemView.findViewById(R.id.imageView);
}
}
public CustomAdapter(ArrayList<DataModel> data) {
this.dataSet = data;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.cards_layout, parent, false);
view.setOnClickListener(MainActivity.myOnClickListener);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
@Override
public void onBindViewHolder(final MyViewHolder holder, final int listPosition) {
TextView textViewName = holder.textViewName;
TextView textViewVersion = holder.textViewVersion;
ImageView imageView = holder.imageViewIcon;
textViewName.setText(dataSet.get(listPosition).getName());
textViewVersion.setText(dataSet.get(listPosition).getVersion());
imageView.setImageResource(dataSet.get(listPosition).getImage());
}
@Override
public int getItemCount() {
return dataSet.size();
}
}
Im obigen Code haben wir unseren eigenen ViewHolder implementiert, indem wir RecyclerView.ViewHolder erweitert haben. Die Ansicht wird aus der cards_layout.xml
aufgeblasen, die wir im Layout-Verzeichnis definiert haben. Der onClickListener in der MainActivity wird an diese Ansicht im folgenden Ausschnitt angehängt.
view.setOnClickListener(MainActivity.myOnClickListener);
Ein ArrayList speichert alle Daten in Form eines DataModel-Klassenobjekts in einem ArrayList und fügt sie den jeweiligen Karten in der Liste hinzu. Die Klassen DataModel.java
und MyData.java
, die die für diese Anwendung spezifischen Daten enthalten, sind unten aufgeführt:
package com.journaldev.recyclerviewcardview;
public class DataModel {
String name;
String version;
int id_;
int image;
public DataModel(String name, String version, int id_, int image) {
this.name = name;
this.version = version;
this.id_ = id_;
this.image=image;
}
public String getName() {
return name;
}
public String getVersion() {
return version;
}
public int getImage() {
return image;
}
public int getId() {
return id_;
}
}
package com.journaldev.recyclerviewcardview;
public class MyData {
static String[] nameArray = {"Cupcake", "Donut", "Eclair", "Froyo", "Gingerbread", "Honeycomb", "Ice Cream Sandwich","JellyBean", "Kitkat", "Lollipop", "Marshmallow"};
static String[] versionArray = {"1.5", "1.6", "2.0-2.1", "2.2-2.2.3", "2.3-2.3.7", "3.0-3.2.6", "4.0-4.0.4", "4.1-4.3.1", "4.4-4.4.4", "5.0-5.1.1","6.0-6.0.1"};
static Integer[] drawableArray = {R.drawable.cupcake, R.drawable.donut, R.drawable.eclair,
R.drawable.froyo, R.drawable.gingerbread, R.drawable.honeycomb, R.drawable.ics,
R.drawable.jellybean, R.drawable.kitkat, R.drawable.lollipop,R.drawable.marsh};
static Integer[] id_ = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
}
Hier ist die Ausgabe unseres Android-RecyclerView- und CardView-Beispielanwendungsprogramms. Wie Sie sehen können, wird das entfernte Element immer an der dritten Position hinzugefügt (vierte Position in der Liste). Damit endet dieses Tutorial zu Android RecyclerView und CardView. Sie können das Android-RecyclerView-CardView-Beispielprojekt über den untenstehenden Link herunterladen.
Laden Sie das Beispielprojekt für Android RecyclerView CardView herunter