Hướng dẫn sử dụng Android CardView

1- Android CardView

Android 5.0 (API Level 21) giới thiệu một thành phần mới đó là CardView, về cơ bản nó là một bộ chứa (container) hình chữ nhật có 4 góc tròn (Rounded Corner), và có hiệu ứng bóng đổ (Shawdow) tại các viền. CardView thường được sử dụng như bộ chứa gốc của các Item trong ListView, GridView hoặc RecyclerView.
Mặc định CardView không có sẵn trong Android SDK, vì vậy muốn sử dụng bạn cần phải thêm thư viện vào project của bạn.
Trên Android Studio bạn có thể cài đặt thư viện CardView từ Palette.
Sau khi cài đặt bạn sẽ thấy thư viện đã được khai báo trên build.gradle (Module: app).
implementation 'androidx.cardview:cardview:1.0.0'
 
Một vài thuộc tính quan trọng của CardView mà bạn nên sét đặt:
  • android:layout_marginLeft
  • android:layout_marginTop
  • android:layout_marginRight
  • android:layout_marginBottom
  • app:cardBackgroundColor

2- Ví dụ CardView

Bây giờ chúng ta sẽ làm một ví dụ với RecyclerViewCardView. OK, đây là hình ảnh xem trước của ví dụ này:
Trên Android Studio tạo một project:
  • File > New > New Project > Empty Activity
    • Name: CardViewExample
    • Package name: org.o7planning.cardviewexample
Cài đặt các thư viện RecyclerViewCardView vào project của bạn:
Sau khi cài đặt bạn sẽ thấy các thư viện đã được khai báo trong build.gradle (Module: app):
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
Bạn cần một vài file ảnh, copy nó vào thư mục drawable của project:
vn.png us.png ru.png jp.png au.png 
Tiếp theo bạn cần tạo ra Layout của RecyclerView Item. Nhấn phải chuột vào thư mục "res/layout" chọn:
  • New > Layout resource file
Nhập vào:
  • File name: recyclerview_item_layout.xml
  • Root element: androidx.cardview.widget.CardView
Thiết kế giao diện của RecyclerView Item:
Mở tập tin recyclerview_item_layout.xml và sét đặt một vài thuộc tính quan trọng cho CardView:
* recyclerview_item_layout.xml *
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="5sp"
    android:layout_marginTop="5sp"
    android:layout_marginRight="5sp"
    android:layout_marginBottom="5sp"
    app:cardBackgroundColor="#FAF5F5">

</androidx.cardview.widget.CardView>
Tiếp tục thiết kế giao diện cho RecyclerView Item:
Điều chỉnh vị trí của các thành phần trên giao diện:
Sét đặt ID, Text, textSize cho các thành phần trên giao diện:
recyclerview_item_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="5sp"
    android:layout_marginTop="5sp"
    android:layout_marginRight="5sp"
    android:layout_marginBottom="5sp"
    app:cardBackgroundColor="#FAF5F5">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageView
            android:id="@+id/imageView_flag"
            android:layout_width="110sp"
            android:layout_height="90sp"
            android:layout_marginStart="16dp"
            android:layout_marginLeft="16dp"
            android:layout_marginTop="16dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:srcCompat="@drawable/ic_launcher_foreground"
            tools:ignore="VectorDrawableCompat" />

        <TextView
            android:id="@+id/textView_countryName"
            android:layout_width="0dp"
            android:layout_height="35dp"
            android:layout_marginStart="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:text="Country Name"
            android:textSize="22sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/imageView_flag"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/textView_population"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginLeft="8dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="16dp"
            android:layout_marginRight="16dp"
            android:text="Popupation"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/imageView_flag"
            app:layout_constraintTop_toBottomOf="@+id/textView_countryName" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
Thiết kế giao diện cho activity_main.xml:
Country.java
package org.o7planning.cardviewexample;

public class Country {

    private String countryName;

    // Image name (Without extension)
    private String flagName;
    private int population;

    public Country(String countryName, String flagName, int population) {
        this.countryName= countryName;
        this.flagName= flagName;
        this.population= population;
    }

    public int getPopulation() {
        return population;
    }

    public void setPopulation(int population) {
        this.population = population;
    }

    public String getCountryName() {
        return countryName;
    }

    public void setCountryName(String countryName) {
        this.countryName = countryName;
    }

    public String getFlagName() {
        return flagName;
    }

    public void setFlagName(String flagName) {
        this.flagName = flagName;
    }

    @Override
    public String toString()  {
        return this.countryName+" (Population: "+ this.population+")";
    }
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:layout_marginRight="16dp"
        android:layout_marginBottom="16dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
CustomRecyclerViewAdapter là lớp mở rộng từ RecyclerView.Adapter, nó làm nhiệm vụ hiển thị dữ liệu lên các RecyclerView Item.
CustomRecyclerViewAdapter.java
package org.o7planning.cardviewexample;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import androidx.recyclerview.widget.RecyclerView;

import java.util.List;

public class CustomRecyclerViewAdapter extends RecyclerView.Adapter<CountryViewHolder> {


    private List<Country> countries;
    private Context context;
    private LayoutInflater mLayoutInflater;

    public CustomRecyclerViewAdapter(Context context, List<Country> datas ) {
        this.context = context;
        this.countries = datas;
        this.mLayoutInflater = LayoutInflater.from(context);
    }

    @Override
    public CountryViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
        // Inflate view from recyclerview_item_layout.xml
        View recyclerViewItem = mLayoutInflater.inflate(R.layout.recyclerview_item_layout, parent, false);

        recyclerViewItem.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                handleRecyclerItemClick( (RecyclerView)parent, v);
            }
        });
        return new CountryViewHolder(recyclerViewItem);
    }


    @Override
    public void onBindViewHolder(CountryViewHolder holder, int position) {
        // Cet country in countries via position
        Country country = this.countries.get(position);

        int imageResId = this.getDrawableResIdByName(country.getFlagName());
        // Bind data to viewholder
        holder.flagView.setImageResource(imageResId);
        holder.countryNameView.setText(country.getCountryName() );
        holder.populationView.setText("Population: "+ country.getPopulation());
    }

    @Override
    public int getItemCount() {
        return this.countries.size();
    }

    // Find Image ID corresponding to the name of the image (in the directory drawable).
    public int getDrawableResIdByName(String resName)  {
        String pkgName = context.getPackageName();
        // Return 0 if not found.
        int resID = context.getResources().getIdentifier(resName , "drawable", pkgName);
        Log.i(MainActivity.LOG_TAG, "Res Name: "+ resName+"==> Res ID = "+ resID);
        return resID;
    }

    // Click on RecyclerView Item.
    private void handleRecyclerItemClick(RecyclerView recyclerView, View itemView) {
        int itemPosition = recyclerView.getChildLayoutPosition(itemView);
        Country country  = this.countries.get(itemPosition);

        Toast.makeText(this.context, country.getCountryName(), Toast.LENGTH_LONG).show();
    }
}
CountryViewHolder.java
package org.o7planning.cardviewexample;

import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

public class CountryViewHolder extends   RecyclerView.ViewHolder {

    ImageView flagView;
    TextView countryNameView;
    TextView populationView;

    // @itemView: recyclerview_item_layout.xml
    public CountryViewHolder(@NonNull View itemView) {
        super(itemView);

        this.flagView = (ImageView) itemView.findViewById(R.id.imageView_flag);
        this.countryNameView = (TextView) itemView.findViewById(R.id.textView_countryName);
        this.populationView = (TextView) itemView.findViewById(R.id.textView_population);
    }
}
MainActivity.java
package org.o7planning.cardviewexample;

import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    public static final String LOG_TAG = "AndroidExample";
    private RecyclerView recyclerView;

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


        List<Country> countries = getListData();
        this.recyclerView = (RecyclerView) this.findViewById(R.id.recyclerView);
        recyclerView.setAdapter(new CustomRecyclerViewAdapter(this, countries));

        // RecyclerView scroll vertical
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        recyclerView.setLayoutManager(linearLayoutManager);
    }

    private  List<Country> getListData() {
        List<Country> list = new ArrayList<Country>();
        Country vietnam = new Country("Vietnam", "vn", 98000000);
        Country usa = new Country("United States", "us", 320000000);
        Country russia = new Country("Russia", "ru", 142000000);
        Country autraylia = new Country("Autraylia", "au", 25000000);
        Country japan = new Country("Japan", "jp", 126000000);

        list.add(vietnam);
        list.add(usa);
        list.add(russia);
        list.add(autraylia);
        list.add(japan);

        return list;
    }


}

Xem thêm các chuyên mục: