Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Làm việc với RecyclerView trong Android Kotlin

Giới thiệu

Ví dụ này minh họa cách triển khai RecyclerView dọc (vertical list) hiển thị danh sách phim với CardView, LinearLayoutManager và Adapter pattern trong Android Kotlin.

Các bước thực hiện

Bước 1: Tạo dự án mới

Mở Android Studio, chọn File → New Project, điền thông tin.

Bước 2: Thêm dependency

dependencies {
    implementation "androidx.recyclerview:recyclerview:1.3.2"
    implementation "androidx.cardview:cardview:1.0.0"
}

Bước 3: Giao diện chính (res/layout/activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:id="@+id/rlMain"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="16dp"
    android:orientation="vertical">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

Bước 4: Model (MovieModel.kt)

data class MovieModel(
    val title: String,
    val genre: String,
    val year: String
)

Bước 5: Layout item (res/layout/item_movie.xml)

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="8dp"
    app:cardBackgroundColor="@android:color/holo_red_dark"
    app:cardCornerRadius="8dp"
    app:cardElevation="4dp">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp">

        <TextView
            android:id="@+id/title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_toStartOf="@id/year"
            android:textColor="@android:color/white"
            android:textSize="18sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/year"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:textColor="@android:color/white"
            android:textSize="14sp" />

        <TextView
            android:id="@+id/genre"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/title"
            android:layout_marginTop="4dp"
            android:textColor="@android:color/white"
            android:textSize="14sp" />

    </RelativeLayout>
</androidx.cardview.widget.CardView>

Bước 6: Adapter (MoviesAdapter.kt)

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.annotation.NonNull
import androidx.recyclerview.widget.RecyclerView

class MoviesAdapter(private val moviesList: List<MovieModel>) :
    RecyclerView.Adapter<MoviesAdapter.MyViewHolder>() {

    inner class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val title: TextView = view.findViewById(R.id.title)
        val year: TextView = view.findViewById(R.id.year)
        val genre: TextView = view.findViewById(R.id.genre)
    }

    @NonNull
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val itemView = LayoutInflater.from(parent.context)
            .inflate(R.layout.item_movie, parent, false)
        return MyViewHolder(itemView)
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val movie = moviesList[position]
        holder.title.text = movie.title
        holder.genre.text = movie.genre
        holder.year.text = movie.year
    }

    override fun getItemCount(): Int = moviesList.size
}

Bước 7: MainActivity.kt

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView

class MainActivity : AppCompatActivity() {
    private val movieList = mutableListOf<MovieModel>()
    private lateinit var moviesAdapter: MoviesAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        title = "KotlinApp"

        val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
        moviesAdapter = MoviesAdapter(movieList)

        val layoutManager = LinearLayoutManager(this)
        recyclerView.layoutManager = layoutManager
        recyclerView.itemAnimator = DefaultItemAnimator()
        recyclerView.adapter = moviesAdapter

        prepareMovieData()
    }

    private fun prepareMovieData() {
        movieList.addAll(listOf(
            MovieModel("Mad Max: Fury Road", "Action & Adventure", "2015"),
            MovieModel("Inside Out", "Animation, Kids & Family", "2015"),
            MovieModel("Star Wars: Episode VII - The Force Awakens", "Action", "2015"),
            MovieModel("Shaun the Sheep", "Animation", "2015"),
            MovieModel("The Martian", "Science Fiction & Fantasy", "2015"),
            MovieModel("Mission: Impossible Rogue Nation", "Action", "2015"),
            MovieModel("Up", "Animation", "2009"),
            MovieModel("Star Trek", "Science Fiction", "2009"),
            MovieModel("The LEGO Movie", "Animation", "2014"),
            MovieModel("Iron Man", "Action & Adventure", "2008"),
            MovieModel("Aliens", "Science Fiction", "1986"),
            MovieModel("Chicken Run", "Animation", "2000"),
            MovieModel("Back to the Future", "Science Fiction", "1985"),
            MovieModel("Raiders of the Lost Ark", "Action & Adventure", "1981"),
            MovieModel("Goldfinger", "Action & Adventure", "1965"),
            MovieModel("Guardians of the Galaxy", "Science Fiction & Fantasy", "2014")
        ))
        moviesAdapter.notifyDataSetChanged()
    }
}

Bước 8: AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="com.example.q11">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>

Chạy ứng dụng

Kết nối thiết bị, nhấn Run. Danh sách phim hiển thị trong RecyclerView với CardView đẹp mắt.

Best Practices:

  • Dùng ListAdapter + DiffUtil cho cập nhật hiệu quả.
  • ViewBinding thay vì findViewById.
  • ViewPager2 cho danh sách ngang.