Android RecyclerView en Android CardView werden geïntroduceerd in Android Lollipop met Material Design. Voor degenen die niet bekend zijn met Material Design, het is een uitgebreide handleiding voor UI-widgets die zijn geïntroduceerd sinds Android 5.0 en het verbetert de visuele aantrekkingskracht van de apps.
Android RecyclerView
Android RecyclerView is een meer geavanceerde, krachtige en flexibele versie van de ListView. Android RecyclerView is vergelijkbaar met ListView behalve dat het ons dwingt om de klasse RecyclerView.ViewHolder te gebruiken om de elementen vast te houden, wat niet verplicht is in ListView. Zoals de naam al aangeeft, wordt Android RecyclerView gebruikt om cellen opnieuw te gebruiken bij het scrollen omhoog en omlaag door de items in de lijst te recyclen. Een andere verbetering in RecyclerView is dat het ons in staat stelt om de LayoutManagers dynamisch in te stellen tijdens runtime, in tegenstelling tot ListView dat alleen beschikbaar was in een verticale scrollende lijst. RecyclerView stelt ons in staat om de volgende soorten lay-outs dynamisch in te stellen tijdens runtime.
- LinearLayoutManager: het ondersteunt zowel verticale als horizontale lijsten
- StaggeredLayoutManager : het ondersteunt gestapelde lijsten
- GridLayoutManager : het ondersteunt het weergeven van roosters zoals eerder te zien in GalleryView
Android RecyclerView-klassen
- De klasse RecyclerView.ItemAnimator biedt betere ondersteuning voor het animeren van de weergaven dan de ListViews
- De klasse RecyclerView.ItemDecorator biedt betere ondersteuning bij het toevoegen van randen en scheiders, waardoor we enorme controle hebben
Dus een RecyclerView is meer aanpasbaar in vergelijking met ListView en geeft meer controle aan de gebruikers. De RecyclerView is beschikbaar in de ondersteuningsbibliotheek. Dus we moeten ons gradle-script aanpassen om de volgende afhankelijkheid toe te voegen.
dependencies {
compile 'com.android.support:recyclerview-v7:21.0.0-rc1'
}
Android CardView
De Android CardView-UI-component toont informatie in kaarten. Deze component wordt over het algemeen gebruikt om contactgegevens weer te geven. Deze component is beschikbaar in een andere ondersteuningsbibliotheek, dus moeten we ook de afhankelijkheid toevoegen.
dependencies {
compile 'com.android.support:cardview-v7:21.0.0-rc1'
compile 'com.android.support:recyclerview-v7:21.0.0-rc1'
}
De Android CardView-widget stelt ons in staat om de achtergrondkleur, schaduw, hoekstraal, elevatie, enz. te controleren. Om de aangepaste attributen in XML te gebruiken, moeten we de volgende namespace-verklaring aan het bovenliggende lay-out toevoegen. Hieronder volgt de namespace-verklaring met enkele attributen uit ons project.
<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">
De belangrijke attributen die hierboven worden gebruikt zijn:
- card_view:cardCornerRadius: Wordt gebruikt om de hoekstraal in onze lay-outs in te stellen
- card_view:cardBackgroundColor: Wordt gebruikt om de achtergrondkleur van de weergave in te stellen
In ons voorbeeldproject voegen we een RecyclerView toe om een lijst met CardViews weer te geven die Android-versienamen en -nummers bevatten, samen met een voorbeeldlogo. De CardView onclick
is geprogrammeerd om die kaart uit de lijst te verwijderen. We hebben een menu-optie toegevoegd aan de ActionBar om de verwijderde kaarten in volgorde terug toe te voegen. Opmerking: De logobeelden zijn willekeurig genomen van Google. Dus de groottes kunnen variëren.
Android RecyclerView en CardView Voorbeeld
Het project bestaat uit een
MainActivity
die de RecyclerView
weergeeft. De CardView wordt aan de RecyclerView toegevoegd vanuit de CustomAdapter-klasse. De DataModel wordt gebruikt om gegevens op te halen voor elke CardView via getters. De MyData-klasse bevat de arrays van tekstweergaven en drawables samen met hun ids.
Android RecyclerView en CardView Voorbeeldcode
De activity_main.xml
bevat de RecyclerView binnen een RelativeLayout zoals hieronder weergegeven. 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>
De lay-out van Android CardView wordt hieronder gedefinieerd: 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>
Android CardView bevat een ImageView samen met twee TextViews in een geneste Lineaire Lay-out. De menu_main.xml
bevat een enkel item om de verwijderde kaarten toe te voegen. 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>
De klasse MainActivity.java
wordt hieronder gedefinieerd:
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) {
// controleer of er items zijn om toe te voegen
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);
}
}
De methode removeItems()
wordt opgeroepen vanuit de luisteraar methode om de geklikte CardView te verwijderen. De bijbehorende id wordt opgeslagen in een array om later op te halen. Om de weergave later toe te voegen, hebben we een andere methode geïmplementeerd met de naam addRemovedItemToList()
. In deze methode voegen we die weergave toe op een vooraf gedefinieerde positie in de lijst en verwijderen we de id ervan uit de removedItems
-array. De CustomAdapter wordt in beide gevallen op de hoogte gebracht. De klasse CustomeAdapter.java is hieronder gedefinieerd:
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();
}
}
In de bovenstaande code hebben we onze eigen ViewHolder geïmplementeerd door RecyclerView.ViewHolder uit te breiden. De weergave wordt opgeblazen vanuit het bestand cards_layout.xml
dat we hebben gedefinieerd in de lay-outs directory. De onClickListener in de MainActivity is gekoppeld aan deze weergave in het onderstaande fragment.
view.setOnClickListener(MainActivity.myOnClickListener);
Een ArrayList slaat alle gegevens op in de vorm van een object van de klasse DataModel in een ArrayList en voegt ze toe aan de respectieve kaarten in de lijst. De klassen DataModel.java
en MyData.java
, die de gegevens specifiek voor deze toepassing bevatten, worden hieronder gegeven:
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};
}
Hieronder staat de output die wordt geproduceerd door onze Android RecyclerView en CardView voorbeeldtoepassing.Zoals je kunt zien, wordt het verwijderde item altijd toegevoegd op de derde index (vierde positie in de lijst). Dit brengt een einde aan deze zelfstudie over Android RecyclerView en CardView. Je kunt het Voorbeeldproject Android RecyclerView CardView downloaden vanaf de onderstaande link.