Thêm danh sách có thể cuộn

1. Trước khi bắt đầu

Trong lớp học lập trình này, bạn sẽ tìm hiểu cách tạo danh sách có thể cuộn trong ứng dụng của mình bằng Jetpack Compose.

Bạn sẽ làm việc với ứng dụng Câu châm ngôn có danh sách lời khẳng định kết hợp với hình ảnh đẹp để mang lại sự tích cực cho ngày của bạn!

Dữ liệu đã có ở đó rồi, bạn chỉ cần lấy dữ liệu đó và hiển thị trong giao diện người dùng.

Điều kiện tiên quyết

  • Quen thuộc với các danh sách trong Kotlin
  • Trải nghiệm bố cục xây dựng bằng Jetpack Compose
  • Trải nghiệm chạy các ứng dụng trên một thiết bị hoặc trình mô phỏng

Nội dung bạn sẽ tìm hiểu

  • Cách tạo thẻ Material Design bằng Jetpack Compose
  • Cách tạo danh sách có thể cuộn bằng Jetpack Compose

Ứng dụng bạn sẽ tạo

  • Bạn sẽ dùng một ứng dụng hiện có và thêm một danh sách có thể cuộn vào giao diện người dùng

Thành phẩm sẽ có dạng như sau:

f6f09800b74f4700.png

Bạn cần có

  • Một máy tính có quyền truy cập Internet, trình duyệt web và Android Studio
  • Quyền truy cập vào GitHub

Tải mã dành cho người mới bắt đầu xuống

Trong Android Studio, hãy mở thư mục basic-android-kotlin-compose-training-affirmations.

  1. Chuyển đến trang kho lưu trữ GitHub được cung cấp cho dự án.
  2. Xác minh rằng tên chi nhánh khớp với tên chi nhánh được chỉ định trong lớp học lập trình. Ví dụ: trong ảnh chụp màn hình sau đây, tên nhánh là main (chính).

1e4c0d2c081a8fd2.png

  1. Trên trang GitHub cho dự án này, hãy nhấp vào nút Code (Mã nguồn), một cửa sổ bật lên sẽ hiện ra.

1debcf330fd04c7b.png

  1. Trong cửa sổ bật lên, nhấp vào nút Download ZIP (Tải tệp ZIP xuống) để lưu dự án vào máy tính. Chờ quá trình tải xuống hoàn tất.
  2. Xác định vị trí của tệp trên máy tính (có thể trong thư mục Tải xuống (Tệp đã tải xuống)).
  3. Nhấp đúp vào tệp ZIP để giải nén. Thao tác này sẽ tạo một thư mục mới chứa các tệp dự án.

Mở dự án trong Android Studio

  1. Khởi động Android Studio.
  2. Trong cửa sổ Welcome to Android Studio (Chào mừng bạn đến với Android Studio), hãy nhấp vào Open (Mở).

d8e9dbdeafe9038a.png

Lưu ý: Nếu Android Studio đã mở sẵn thì hãy chuyển sang chọn tuỳ chọn File (Tệp) > Open (Mở) trên trình đơn.

8d1fda7396afe8e5.png

  1. Trong trình duyệt tệp, hãy chuyển đến vị trí của thư mục dự án chưa giải nén (có thể nằm trong thư mục Downloads (Tệp đã tải xuống)).
  2. Nhấp đúp vào thư mục dự án đó.
  3. Chờ Android Studio mở dự án.
  4. Nhấp vào nút Run (Chạy) 8de56cba7583251f.png để tạo và chạy ứng dụng. Đảm bảo rằng ứng dụng được xây dựng như dự kiến.

2. Xem video tập lập trình (Không bắt buộc)

Nếu bạn muốn xem một trong những người hướng dẫn của khoá học hoàn thành lớp học lập trình, hãy phát video bên dưới.

Bạn nên mở rộng video ra toàn màn hình (có biểu tượng Biểu tượng này hiển thị 4 góc trên một hình vuông được làm nổi bật để biểu thị chế độ toàn màn hình. ở góc dưới bên phải của video). Nhờ đó, bạn có thể nhìn thấy Android Studio và mã rõ ràng hơn.

Bước này là bước không bắt buộc. Bạn cũng có thể bỏ qua video này và bắt đầu tham gia lớp học lập trình ngay.

3. Tạo một lớp dữ liệu mục trong danh sách

Tạo một lớp dữ liệu cho một Thông báo xác nhận

Trong ứng dụng Android, danh sách bao gồm các mục trong danh sách. Đối với các phần dữ liệu đơn lẻ, dữ liệu này có thể đơn giản như một chuỗi hoặc một số nguyên. Đối với những mục trong danh sách có nhiều phần dữ liệu, chẳng hạn như hình ảnh và văn bản, bạn sẽ cần một lớp chứa tất cả các thuộc tính này. Lớp dữ liệu là một loại chỉ chứa các thuộc tính, có thể cung cấp một số phương thức hữu ích để làm việc với các thuộc tính đó.

  1. Tạo một gói mới trong mục com.example.affirmations. 4a51cb670bbec405.png

Đặt tên cho mẫu gói mới. Gói mô hình sẽ chứa mô hình dữ liệu mà sẽ được biểu thị bằng một lớp dữ liệu. Lớp dữ liệu đó sẽ bao gồm các thuộc tính đại diện cho thông tin liên quan đến "Xác nhận", bao gồm tài nguyên chuỗi và tài nguyên hình ảnh. Gói là các thư mục chứa các lớp và thậm chí là các thư mục khác.

9ea1f8880ca90ea0.png

  1. Tạo một lớp mới trong gói com.example.affirmations.model. a9515a8b47715a22.png

Đặt tên cho lớp mới là Xác nhận và đặt lớp đó là Lớp dữ liệu.

b36be7f428fd1672.png

  1. Mỗi Affirmation bao gồm một hình ảnh và một chuỗi. Tạo hai thuộc tính val trong lớp dữ liệu Affirmation. Một giá trị sẽ được gọi là stringResourceId và giá trị còn lại là imageResourceId. Cả hai mã này đều phải là số nguyên.

Affirmation.kt

data class Affirmation(
   val stringResourceId: Int,
   val imageResourceId: Int
)
  1. Gắn thẻ thuộc tính stringResourceId với chú thích @StringRes và gắn thẻ imageResourceId bằng @DrawableRes. stringResourceId đại diện cho mã cho văn bản xác nhận được lưu trữ trong một tài nguyên chuỗi. imageResourceId đại diện cho mã nhận dạng cho hình ảnh xác nhận được lưu trữ trong một tài nguyên có thể vẽ.

Affirmation.kt

data class Affirmation(
   @StringRes val stringResourceId: Int,
   @DrawableRes val imageResourceId: Int
)
  1. Bây giờ, hãy mở tệp Datasource.kt trong gói com.example.affirmations.data và hủy nhận xét về nội dung của lớp Datasource.

Datasource.kt

class Datasource() {
   fun loadAffirmations(): List<Affirmation> {
       return listOf<Affirmation>(
           Affirmation(R.string.affirmation1, R.drawable.image1),
           Affirmation(R.string.affirmation2, R.drawable.image2),
           Affirmation(R.string.affirmation3, R.drawable.image3),
           Affirmation(R.string.affirmation4, R.drawable.image4),
           Affirmation(R.string.affirmation5, R.drawable.image5),
           Affirmation(R.string.affirmation6, R.drawable.image6),
           Affirmation(R.string.affirmation7, R.drawable.image7),
           Affirmation(R.string.affirmation8, R.drawable.image8),
           Affirmation(R.string.affirmation9, R.drawable.image9),
           Affirmation(R.string.affirmation10, R.drawable.image10))
   }
}

4. Thêm danh sách vào ứng dụng

Tạo thẻ mục danh sách

Ứng dụng này nhằm hiển thị danh sách khẳng định. Bước đầu tiên trong việc định cấu hình giao diện người dùng để hiển thị danh sách là tạo một mục trong danh sách. Mỗi mục khẳng định bao gồm một hình ảnh và một chuỗi. Dữ liệu cho từng mục này đi kèm với mã khởi động và bạn sẽ tạo thành phần giao diện người dùng để hiển thị mục đó.

Mục này sẽ bao gồm một thành phần Card tổng hợp, chứa Image và một thành phần Text. Trong Soạn thư, Card là một nền tảng hiển thị nội dung và các hành động trong một vùng chứa duy nhất. Thẻ Lời xác nhận sẽ có dạng như sau:

95111184aed54fa3.png

Thẻ hiển thị một hình ảnh có một số văn bản bên dưới. Bạn có thể đạt được bố cục dọc này bằng cách dùng Column kết hợp được gói trong một trình tổng hợp Card. Bạn có thể tự mình thử nghiệm hoặc làm theo các bước dưới đây để đạt được mục tiêu.

  1. Mở tệp MainActivity.kt.

1e348baaf91552f4.png

  1. Tạo một phương thức mới bên dưới phương thức AffirmationApp(), được gọi là AffirmationCard() và chú thích phương thức đó bằng chú thích @Composable.

MainActivity.kt

@Composable
fun AffirmationApp() {
   val context = LocalContext.current
   AffirmationsTheme {

   }
}

@Composable
fun AffirmationCard() {

}
  1. Chỉnh sửa chữ ký của phương thức để lấy đối tượng Affirmation làm thông số. Đối tượng Affirmation đến từ gói model.

MainActivity.kt

@Composable
fun AffirmationCard(affirmation: Affirmation) {

}
  1. Thêm một tham số modifier vào chữ ký. Đặt giá trị mặc định là Modifier cho thông số.

MainActivity.kt

@Composable
fun AffirmationCard(affirmation: Affirmation, modifier: Modifier = Modifier) {

}
  1. Bên trong phương thức AffirmationCard, hãy gọi lệnh Card tổng hợp. Chuyển các thông số sau: modifierelevation. Chuyển một đối tượng Modifier có thuộc tính padding được đặt thành 8.dp cho thông số modifier. Chuyển giá trị của 4.dp cho elevation. Tài sản elevation sẽ được trình bày chi tiết hơn ở phần sau.

MainActivity.kt

@Composable
fun AffirmationCard(affirmation: Affirmation, modifier: Modifier = Modifier) {Card(modifier = modifier.padding(8.dp), elevation = 4.dp) {
  }
}
  1. Thêm một bộ tổng hợp Column bên trong bộ tổng hợp Card. Các mục trong một tổ hợp Column sẽ tự sắp xếp theo chiều dọc trong giao diện người dùng. Điều này cho phép bạn đặt hình ảnh lên phía trên văn bản được liên kết. Ngược lại, Row tổng hợp được sắp xếp các mục được chứa theo chiều ngang.

MainActivity.kt

@Composable
fun AffirmationCard(affirmation: Affirmation, modifier: Modifier = Modifier) {
  Card(modifier = modifier.padding(8.dp), elevation = 4.dp) {
    Column {
    }
  }
}
  1. Thêm một thành phần kết hợp Image bên trong phần nội dung lambda của thành phần tổng hợp Column. Hãy nhớ là thành phần kết hợp Image luôn yêu cầu hiển thị tài nguyên và contentDescription. Tài nguyên phải là painterResource được chuyển vào thông số painter. Phương thức painterResource sẽ tải các tài nguyên có thể vẽ hoặc vectơ đã tạo điểm ảnh như PNG. Ngoài ra, hãy chuyển stringResource cho thông số contentDescription.

MainActivity.kt

@Composable
fun AffirmationCard(affirmation: Affirmation, modifier: Modifier = Modifier) {
  Card(modifier = Modifier.padding(8.dp), elevation = 4.dp) {
    Column {
      Image(
        painter = painterResource(affirmation.imageResourceId),
        contentDescription = stringResource(affirmation.stringResourceId)
      )
    }
  }
}
  1. Ngoài các thông số paintercontentDescription, hãy chuyển modifiercontentScale. contentScale xác định cách thu nhỏ và hiển thị hình ảnh. Đối tượng Modifier phải được đặt thuộc tính fillMaxWidth và chiều cao là 194.dp. contentScale phải là ContentScale.Crop.

MainActivity.kt

@Composable
fun AffirmationCard(affirmation: Affirmation, modifier: Modifier = Modifier) {
  Card(modifier = Modifier.padding(8.dp), elevation = 4.dp) {
    Column {
      Image(
        painter = painterResource(affirmation.imageResourceId),
        contentDescription = stringResource(affirmation.stringResourceId),
        modifier = Modifier
          .fillMaxWidth()
          .height(194.dp),
        contentScale = ContentScale.Crop
      )
    }
  }
}
  1. Bên trong Column, hãy tạo một bản tổng hợp Text sau bản tổng hợp Image. Chuyển stringResource của affirmation.stringResourceId đến thông số text, chuyển đối tượng Modifier với thuộc tính padding được đặt thành 16.dp và đặt giao diện văn bản bằng cách chuyển MaterialTheme.typography.h6 vào thông số style.

MainActivity.kt

@Composable
fun AffirmationCard(affirmation: Affirmation, modifier: Modifier = Modifier) {
  Card(modifier = Modifier.padding(8.dp), elevation = 4.dp) {
    Column {
      Image(
        painter = painterResource(affirmation.imageResourceId),
        contentDescription = stringResource(affirmation.stringResourceId),
        modifier = Modifier
          .fillMaxWidth()
          .height(194.dp),
        contentScale = ContentScale.Crop
      )
      Text(
        text = stringResource(affirmation.stringResourceId),
        modifier = Modifier.padding(16.dp),
        style = MaterialTheme.typography.h6
      )
    }
  }
}

Xem trước thẻ AffirmationCard

Thẻ này là lõi của giao diện người dùng cho ứng dụng Câu châm ngôn và bạn đã nỗ lực để tạo thẻ đó! Để kiểm tra xem thẻ có chính xác hay không, bạn có thể tạo một trình tổng hợp có thể xem trước mà không cần khởi chạy toàn bộ ứng dụng.

  1. Tạo một phương thức riêng tư có tên là AffirmationCardPreview(). Chú thích phương thức bằng @Preview@Composable.

MainActivity.kt

@Preview
@Composable
private fun AffirmationCardPreview() {
}
  1. Bên trong phương thức, hãy gọi trình tổng hợp AffirmationCard và chuyển đối tượng đó thành đối tượng Affirmation mới với tài nguyên chuỗi R.string.affirmation1 và tài nguyên có thể vẽ R.drawable.image1 được chuyển vào hàm dựng.

MainActivity.kt

@Preview
@Composable
private fun AffirmationCardPreview() {
  AffirmationCard(Affirmation(R.string.affirmation1, R.drawable.image1))
}
  1. Mở thẻ Tách và bạn sẽ thấy bản xem trước của AffirmationCard. Nếu cần, hãy nhấp vào Tạo và làm mới trong ngăn Thiết kế để hiển thị bản xem trước. 84904da4a33413ce.png

Tạo danh sách

Thành phần của mục danh sách là yếu tố nền tảng của danh sách. Sau khi đã tạo mục danh sách, bạn có thể tận dụng mục đó để tạo thành phần danh sách.

  1. Tạo một phương thức có tên là AffirmationList(), chú thích bằng chú thích @Composable và khai báo List của đối tượng Affirmation làm thông số trong chữ ký của phương thức.

MainActivity.kt

@Composable
private fun AffirmationList(affirmationList: List<Affirmation>) {
}
  1. Khai báo một đối tượng modifier dưới dạng một thông số trong chữ ký phương thức có giá trị mặc định là Modifier.

MainActivity.kt

@Composable
private fun AffirmationList(affirmationList: List<Affirmation>, modifier: Modifier = Modifier) {
}
  1. Trong Jetpack Compose, bạn có thể tạo một danh sách có thể cuộn bằng cách sử dụng trình tổng hợp LazyColumn. Sự khác biệt giữa LazyColumnColumnColumn phải được sử dụng khi bạn có một số ít các mục để hiển thị, vì Compose sẽ tải tất cả các mục này cùng một lúc. Column chỉ có thể giữ một số thành phần tổng hợp được xác định trước hoặc cố định. LazyColumn có thể thêm nội dung theo yêu cầu, phù hợp với danh sách dài và đặc biệt khi không xác định được độ dài của danh sách. Theo mặc định, LazyColumn cũng cung cấp chức năng cuộn mà không cần thêm mã. Khai báo một trình tổng hợp LazyColumn bên trong phương thức AffirmationList().

MainActivity.kt

@Composable
private fun AffirmationList(affirmationList: List<Affirmation>, modifier: Modifier = Modifier) {
  LazyColumn {
  }
}
  1. Trong phần nội dung hàm lambda của LazyColumn, hãy gọi phương thức items() và chuyển vào affirmationList. Phương thức items() là cách bạn thêm các mục vào LazyColumn. Phương pháp này có phần khác biệt đối với tài sản tổng hợp này và không phải là phương pháp phổ biến đối với hầu hết các tài liệu tổng hợp.

MainActivity.kt

@Composable
private fun AffirmationList(affirmationList: List<Affirmation>, modifier: Modifier = Modifier) {
  LazyColumn {
    items(affirmationList){
    }
  }
}
  1. Lệnh gọi đến phương thức items() yêu cầu hàm lambda. Trong hàm đó, hãy chỉ định tham số affirmation đại diện cho một mục khẳng định từ affirmationList.

MainActivity.kt

@Composable
private fun AffirmationList(affirmationList: List<Affirmation>, modifier: Modifier = Modifier) {
  LazyColumn {
    items(affirmationList){ affirmation ->
    }
  }
}
  1. Đối với mỗi lời khẳng định trong danh sách, hãy gọi AffirmationCard() tổng hợp và chuyển hàm affirmation.

MainActivity.kt

@Composable
private fun AffirmationList(affirmationList: List<Affirmation>, modifier: Modifier = Modifier) {
  LazyColumn {
    items(affirmationList){ affirmation ->
      AffirmationCard(affirmation)
    }
  }
}

Hiển thị danh sách

  1. Trong hàm lambda, hãy gọi hàm AffirmationList tổng hợp và chuyển DataSource().loadAffirmations() vào thông số affirmationList.

MainActivity.kt

@Composable
fun AffirmationApp() {
   AffirmationsTheme {
       Scaffold(
           content = {
               AffirmationList(affirmationList = Datasource().loadAffirmations())
           }
       )
   }
}

Chạy ứng dụng Câu châm ngôn trên thiết bị hoặc trình mô phỏng và xem sản phẩm đã hoàn thành!

f6f09800b74f4700.png

5. Lấy mã giải pháp

Nếu bạn muốn xem mã giải pháp, hãy xem mã trên GitHub.

  1. Chuyển đến trang kho lưu trữ GitHub được cung cấp cho dự án.
  2. Xác minh rằng tên chi nhánh khớp với tên chi nhánh được chỉ định trong lớp học lập trình. Ví dụ: trong ảnh chụp màn hình sau đây, tên nhánh là main (chính).

1e4c0d2c081a8fd2.png

  1. Trên trang GitHub cho dự án này, hãy nhấp vào nút Code (Mã nguồn), một cửa sổ bật lên sẽ hiện ra.

1debcf330fd04c7b.png

  1. Trong cửa sổ bật lên, nhấp vào nút Download ZIP (Tải tệp ZIP xuống) để lưu dự án vào máy tính. Chờ quá trình tải xuống hoàn tất.
  2. Xác định vị trí của tệp trên máy tính (có thể trong thư mục Tải xuống (Tệp đã tải xuống)).
  3. Nhấp đúp vào tệp ZIP để giải nén. Thao tác này sẽ tạo một thư mục mới chứa các tệp dự án.

Mở dự án trong Android Studio

  1. Khởi động Android Studio.
  2. Trong cửa sổ Welcome to Android Studio (Chào mừng bạn đến với Android Studio), hãy nhấp vào Open (Mở).

d8e9dbdeafe9038a.png

Lưu ý: Nếu Android Studio đã mở sẵn thì hãy chuyển sang chọn tuỳ chọn File (Tệp) > Open (Mở) trên trình đơn.

8d1fda7396afe8e5.png

  1. Trong trình duyệt tệp, hãy chuyển đến vị trí của thư mục dự án chưa giải nén (có thể nằm trong thư mục Downloads (Tệp đã tải xuống)).
  2. Nhấp đúp vào thư mục dự án đó.
  3. Chờ Android Studio mở dự án.
  4. Nhấp vào nút Run (Chạy) 8de56cba7583251f.png để tạo bản dựng và chạy ứng dụng. Đảm bảo ứng dụng được xây dựng như mong đợi.

6. Kết luận

Giờ đây, bạn đã biết cách tạo thẻ, liệt kê các mục và danh sách có thể cuộn bằng Jetpack Compose! Xin lưu ý rằng đây chỉ là những công cụ cơ bản để tạo danh sách. Bạn có thể thỏa sức sáng tạo và tùy chỉnh các mục danh sách theo ý muốn!

Tóm tắt

  • Sử dụng Card thành phần để tạo mục danh sách.
  • Sửa đổi giao diện người dùng nằm trong trình tổng hợp Card.
  • Tạo một danh sách có thể cuộn bằng cách sử dụng trình tổng hợp LazyColumn.
  • Tạo danh sách bằng cách sử dụng các mục trong danh sách tùy chỉnh.