Android RecyclerView, Android CardView Voorbeeld Tutorial

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.

Download het Android RecyclerView CardView voorbeeldproject

Source:
https://www.digitalocean.com/community/tutorials/android-recyclerview-android-cardview-example-tutorial