![đồ án 2 xây dựng ứng dụng chia sẻ công thức món ăn](https://123docz.net/image/doc_normal.png)
Đang tải... (xem toàn văn)
Thông tin tài liệu
Bằng cách sử dụng Compose, bạn có thể xây dựng giao diện người dùng bằng cách xác định một tập hợp các hàm có khả năng kết hợp lấy dữ liệu và cung cấp các thành phần trên giao diện người
Trang 1TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN KHOA CÔNG NGHỆ PHẦN MỀM
- -
BÁO CÁO ĐỒ ÁN 2 Đề tài:
XÂY DỰNG ỨNG DỤNG CHIA SẺ CÔNG THỨC MÓN ĂN
Giảng viên hướng dẫn: ThS Huỳnh Tuấn Anh Lớp: SE122.O11
Trang 3LỜI CẢM ƠN
Sau quá trình học tập và rèn luyện tại khoa Công nghệ phần mềm trường Đại học Công nghệ Thông tin – ĐHQG TP.HCM, em đã được trang bị các kiến thức cơ bản cùng các kỹ năng thực tế để có thể hoàn thành Đồ án 2 của mình
Để hoàn thành đồ án này, với lòng biết ơn sâu sắc em xin gửi lời cảm ơn chân thành đến:
Ban Giám hiệu trường Đại học Công nghệ Thông tin – ĐHQG TP.HCM vì đã tạo điều kiện thuận lợi để sinh viên tìm kiếm, nghiên cứu thông tin với hệ thống thư viện hiện đại, đa dạng các loại sách và tài liệu
Gần gũi hơn là những lời tốt đẹp nhất xin gửi đến đến thầy Nguyễn Công Hoan đã tận tình giúp đỡ, định hướng cách tư duy và hướng làm việc khoa học Đó là những góp ý hết sức quý báu không chỉ trong quá trình thực hiện đồ án mà còn là hành trang tiếp bước cho em trong quá trình học tập và làm việc sau này
Sau cùng, xin chúc quý Thầy Cô trong khoa Công nghệ Phần mềm nói riêng cũng như các giáo viên tại trường Công nghệ thông tin nói chung thật dồi dào sức khỏe, niềm tin để tiếp tục thực hiện sứ mệnh cao đẹp của mình
Thành phố Hồ Chí Minh, tháng 12 năm 2023 Sinh Viên
Bùi Lê Hoài An
Trang 4NHẬN XÉT CỦA GIẢNG VIÊN
Trang 5MỤC LỤC
LỜI CẢM ƠN 3
NHẬN XÉT CỦA GIẢNG VIÊN 4
MỤC LỤC 5
CHƯƠNG 1: GIỚI THIỆU TỔNG QUAN 9
1.Thông tin sinh viên: 9
2.Tổng quan đề tài: 9
2.1Giới thiệu đề tài: 9
2.2Phạm vi nghiên cứu: 9
2.3Nội dung nghiên cứu: 9
2.4Kết quả hướng tới: 10
3.Công cụ sử dụng: 10
CHƯƠNG 2: CÔNG NGHỆ SỬ DỤNG 11
1.Giới thiệu ngôn ngữ lập trình Kotlin 11
2.Jetpack Compose 11
3.Tại sao lại là Jetpack Compose? 12
4.Mô hình tư duy trong Jetpack Compose 12
4.1.Mô hình lập trình khai báo 13
4.2.Hàm composable đơn giản 13
4.3.Thay đổi mô hình khai báo 15
4.4.Nội dung động 17
4.5.Recomposition 18
4.5.1.Các hàm composable có thể thực thi theo thứ tự bất kỳ 19
4.5.2.Các hàm composable có thể chạy song song 19
Trang 65.4.Mô hình bố cục 27
5.5.Hiệu suất 29
5.6.Sử dụng modifiers 29
6.Quản lý trạng thái 30
6.1.Trạng thái và composition 31
6.2.Trạng thái trong composition 32
6.3.Chuyển trạng thái lên trên 33
6.4.Khôi phục trạng thái 36
6.4.1.Parcelize 36
6.4.2.MapSaver 37
6.5.Phần tử giữ trạng thái 37
6.6.Kích hoạt lại tính năng ghi nhớ các tính toán khi khoá thay đổi 37
7.Vòng đời của Composable 39
7.1.Tổng quan 39
7.2.Phân tích một Composable trong Composition 41
7.2.1.Thêm thông tin hỗ trợ quá trình recomposition 42
7.3.Bỏ qua nếu giá trị đầu vào không thay đổi 46
8.Các giai đoạn trong Jetpack Compose 47
8.1.3 giai đoạn của một frame 47
8.2.Đọc trạng thái 49
8.3.Đọc trạng thái theo giai đoạn 50
8.3.1.Giai đoạn 1: Composition 50
8.3.2.Giai đoạn 2: Layout 50
8.3.3.Giai đoạn 3: Drawing 51
8.4.Tối ưu hóa việc đọc trạng thái 52
8.5.Vòng lặp tái kết hợp (phần phụ thuộc giai đoạn tuần hoàn) 54
Trang 71.3.Đối tượng hướng đến 59
1.4.Môi trường phát triển ứng dụng 59
1.5.Kết quả mong đợi 60
1.6.Quy trình thực hiện các công việc chính 60
2.Phân tích, thiết kế hệ thống 60
2.1.Xác định và mô hình hóa các yêu cầu phần mềm 60
2.1.1.Xác định yêu cầu 60
2.1.1.1 Một số yêu cầu phần mềm phải có 60
2.1.1.2 Ràng buộc logic ban đầu 61
2.2.Thiết kế hệ thống 77
2.2.1.Kiến trúc hệ thống: Multi module architecture 77
2.2.1.1 Vấn đề về độ lớn của mã 77
2.2.1.2 Module hóa 77
2.2.2.Kiến trúc ứng dụng 78
2.3.Thiết kế dữ liệu 80
2.4.Thiết kế giao diện 85
2.4.1.Sơ đồ liên kết màn hình 85
2.4.2.Danh sách các màn hình 86
3.Cài đặt và thử nghiệm 105
Trang 9CHƯƠNG 1: GIỚI THIỆU TỔNG QUAN
1 Thông tin sinh viên:
20520985 Bùi Lê Hoài An 20520985@gm.uit.edu.vn
2 Tổng quan đề tài:
Chúng ta không thể phủ nhận sự hữu ích của các framework platform (Flutter, React-Native, …) đã giúp chúng ta phần nào giải quyết được vấn đề về mặt thời gian Tuy vậy khi nhìn vào thực tế, các công ty lớn trên thế giới tiếp tục sử dụng các ứng dụng native, đó là vấn đề lớn cũng cần phải được kể đến: hiệu suất Hiệu suất ảnh hưởng trực tiếp đến trải nghiệm người dùng Vì thế phát triển ứng dụng
coss-Phát triển ứng dụng native từ lâu đã tồn tại những yếu điểm dễ dàng nhận thấy Đơn cử như đối với Android, đó là việc nhà phát triển phải sử dụng một loại ngôn ngữ khác hoàn toàn với ngôn ngữ chính để lập trình – XML Đối với các nhà phát triển cũng như các công ty phải học song song 2 ngôn ngữ (Java/Kotlin và XML) là rất mất thời gian, dẫn đến đó là tiêu tốn nhiều chi phí
Kể từ sau Google I/O 2019, Kotlin dần phát triển để thay thế Java, trở thành một ngôn ngữ lập trình được ưa chuộng nhất cho phát triển ứng dụng Android native Và điều chúng ta mong muốn nhất rồi cũng đến: Jetpack Compose, sử dụng Kotlin làm ngôn ngữ lập trình đã ra đời với nhiệm vụ tiên quyết: source code chỉ chứa duy nhất 1 ngôn ngữ lập trình
Trang 10Em sẽ tiến hành nghiên cứu chi tiết về cách thức hoạt động, ưu - khuyết điểm cũng như các thư viện - tính năng - package liên quan đến Compose
Với đề tài này, em đề ra hai mục tiêu chính:
• Đối với các nhân: mở rộng kiến thức của mình về Compose thông qua quá trình tìm hiểu và áp dụng vào ứng dụng thực tế Các kiến thức tìm hiểu được thông qua đồ án thúc đẩy em phát triển thêm các ứng dụng khác bằng Compose Jetpack Đồng thời, em học được cách nghiên cứu và sử dụng một framework mới cần trải qua quá trình gì nhằm giúp em dễ dàng tiếp xúc với các công nghệ mới hơn trong tương lai
• Có cái nhìn tổng quát hơn trong việc ứng dụng Machine Learning trong phát triển ứng dụng mobile
3 Công cụ sử dụng:
Trong quá trình xây dựng phần mềm, em đã sử dụng các phần mềm sau:
• Android Studio: phát triển front end • Google Colabs: training model • GitHub: quản lý source code
Trang 11CHƯƠNG 2: CÔNG NGHỆ SỬ DỤNG
1 Giới thiệu ngôn ngữ lập trình Kotlin
Kotlin là một ngôn ngữ lập trình đa năng, được thiết kế để chạy trên nền tảng Java Virtual Machine (JVM), nhưng cũng có thể chạy trên nền tảng Android, JavaScript và Native Kotlin được phát triển bởi JetBrains, cùng với một số cộng đồng lập trình viên đóng góp
Một số đặc điểm của Kotlin bao gồm:
• Kotlin là một ngôn ngữ lập trình hướng đối tượng (OOP) và hỗ trợ các khái niệm lập trình hàm (FP), giúp cho việc phát triển ứng dụng linh hoạt hơn • Kotlin có cú pháp đơn giản, dễ đọc và dễ viết hơn so với Java và nhiều
Kotlin đã được Google chính thức công nhận là ngôn ngữ lập trình cho phát triển ứng dụng Android, và được sử dụng rộng rãi trong cộng đồng lập trình viên Android Ngoài ra, Kotlin cũng được sử dụng trong nhiều dự án khác, bao gồm phát triển trên máy chủ, ứng dụng web và phát triển ứng dụng trên các thiết bị nhúng
2 Jetpack Compose
Jetpack Compose là một thư viện UI cho phép bạn xây dựng giao diện người dùng Android bằng cách sử dụng Kotlin Nó cho phép tạo các giao diện người dùng tùy chỉnh và linh hoạt hơn Bạn có thể tạo các giao diJetpack Compose là một framework để phát triển giao diện người dùng (UI) trên nền tảng Android, được phát triển bởi Google Nó cho phép lập trình viên tạo giao diện người dùng bằng
Trang 123 Tại sao lại là Jetpack Compose?
• Khai báo giao diện người dùng: Jetpack Compose sử dụng phong cách lập trình khai báo, cho phép bạn xác định giao diện bằng cách chỉ định những gì bạn muốn nó hiển thị, thay vì xác định cách để đạt được nó Điều này làm cho mã dễ đọc, dễ hiểu hơn và dễ bảo trì hơn so với phương pháp truyền thống sử dụng XML
• Dễ dàng tích hợp: Jetpack Compose tích hợp tốt với các thành phần và công nghệ hiện có của Android, cho phép bạn sử dụng các tính năng mạnh mẽ khác như ViewModel, LiveData và Room để quản lý trạng thái ứng dụng và tương tác với cơ sở dữ liệu
• Hiệu suất cao hơn: Jetpack Compose được tối ưu để cung cấp hiệu suất cao hơn so với phương pháp truyền thống Compose sử dụng một cơ chế gọi là "Recompose" để chỉ cập nhật lại các phần tử giao diện người dùng đã thay đổi thay vì cập nhật toàn bộ giao diện Điều này giúp giảm tải cho CPU và cải thiện hiệu suất của ứng dụng
• Tương thích và tái sử dụng tốt hơn: Jetpack Compose được thiết kế để tương thích với các phiên bản Android cũ hơn và mới hơn Bạn có thể sử dụng Compose trong các dự án hiện có hoặc tích hợp nó với mã Java/Kotlin truyền thống Ngoài ra, Jetpack Compose cũng khuyến khích tái sử dụng mã và các thành phần giao diện người dùng, giúp tiết kiệm thời gian và công sức trong quá trình phát triển
• Cộng đồng mạnh mẽ: Jetpack Compose đã nhận được sự hỗ trợ rất lớn từ cộng đồng phát triển Android Có nhiều tài liệu, ví dụ mã và nguồn tài nguyên hữu ích được chia sẻ trên trang web của Google và từ các nhà phát triển khác trên Internet Bạn cũng có thể nhận được sự hỗ trợ từ cộng đồng qua các diễn đàn, nhóm Facebook, và các nhóm Telegram
Tổng thể, Jetpack Compose là một framework mạnh mẽ và tiện ích cho việc phát triển giao diện người dùng Android Nó giúp bạn tăng năng suất, cải thiện hiệu suất ứng dụng và tạo ra giao diện linh hoạt, tương tác
4 Mô hình tư duy trong Jetpack Compose
Jetpack Compose là bộ công cụ khai báo giao diện người dùng hiện đại cho Android Compose sẽ giúp bạn dễ dàng ghi và duy trì giao diện người dùng ứng dụng bằng cách cung cấp API khai báo cho phép bạn hiển thị giao diện người dùng
Trang 13của ứng dụng mà không cần ra lệnh thay đổi các chế độ xem giao diện người dùng Thuật ngữ này cần được giải thích đôi chút nhưng có ý nghĩa rất quan trọng đối với cách thiết kế ứng dụng của bạn
4.1 Mô hình lập trình khai báo
Trước đây, hệ phân cấp chế độ xem Android được biểu thị dưới dạng cây tiện ích giao diện người dùng Khi trạng thái của ứng dụng thay đổi vì những yếu tố như hoạt động tương tác của người dùng, bạn cần cập nhật hệ thống phân cấp giao diện người dùng để hiển thị dữ liệu hiện tại Cách phổ biến nhất để cập nhật giao diện người dùng là hướng dẫn cho cây bằng các hàm như findViewById() và thay đổi các nút bằng những phương thức gọi như button.setText(String), container.addChild(View) hoặc img.setImageBitmap(Bitmap) Các phương thức này thay đổi trạng thái nội bộ của tiện ích
Việc điều chỉnh chế độ xem theo cách thủ công sẽ làm tăng khả năng xảy ra lỗi Nếu một phần dữ liệu hiển thị ở nhiều vị trí thì bạn sẽ có thể quên cập nhật một trong các chế độ xem hiển thị dữ liệu đó Việc tạo các trạng thái không hợp lệ cũng rất dễ xảy ra khi hai lượt cập nhật xung đột theo cách không mong đợi Ví dụ: một lượt cập nhật có thể cố gắng đặt một giá trị nút vừa mới bị xoá khỏi giao diện người dùng Nói chung, độ phức tạp của việc bảo trì phần mềm tăng lên cùng với số chế độ xem cần cập nhật
Trong vài năm qua, toàn bộ ngành đã bắt đầu chuyển sang mô hình giao diện người dùng khai báo, giúp đơn giản hoá rất nhiều kỹ thuật liên quan đến việc xây dựng và cập nhật giao diện người dùng Kỹ thuật này hoạt động bằng cách tạo lại từ đầu toàn bộ màn hình, sau đó chỉ áp dụng những thay đổi cần thiết Phương pháp này giúp bạn dễ dàng cập nhật hệ phân cấp chế độ xem có trạng thái theo cách thủ công Compose là một khung giao diện người dùng khai báo
Một khó khăn trong việc tạo lại toàn bộ màn hình là giải pháp này có thể tốn
Trang 14Bằng cách sử dụng Compose, bạn có thể xây dựng giao diện người dùng bằng cách xác định một tập hợp các hàm có khả năng kết hợp lấy dữ liệu và cung cấp các thành phần trên giao diện người dùng Một ví dụ đơn giản là hàm Greeting lấy String và cung cấp Text hiển thị tin nhắn chào mừng
Hình 1 Một hàm có khả năng kết hợp đơn giản được chuyển dữ liệu và sử dụng dữ
liệu này để hiển thị một tiện ích văn bản trên màn hình Vài điều đáng chú ý về hàm này:
• Hàm này được chú thích bằng chú thích @Composable Tất cả hàm có khả năng kết hợp đều phải có chú thích này; chú thích này sẽ thông báo cho trình biên dịch Compose rằng hàm này có mục đích chuyển đổi dữ liệu thành giao diện người dùng
• Hàm này lấy dữ liệu Các hàm có khả năng kết hợp có thể chấp nhận các thông số cho phép logic của ứng dụng mô tả giao diện người dùng Trong trường hợp này, tiện ích của chúng tôi chấp nhận String để có thể chào người dùng theo tên
• Hàm này hiển thị văn bản trong giao diện người dùng Hàm này thực hiện tính năng này bằng cách gọi hàm có khả năng kết hợp Text() - hàm thực sự tạo ra thành phần văn bản trên giao diện người dùng Hàm có khả năng kết hợp cung cấp sự phân cấp giao diện người dùng bằng cách gọi các hàm có khả năng kết hợp khác
Trang 15• Hàm này không trả về bất kỳ giá trị nào Các hàm Compose cung cấp giao diện người dùng không cần trả về bất cứ điều gì vì các hàm này mô tả trạng thái màn hình mong muốn thay vì tạo các tiện ích giao diện người dùng • Hàm này nhanh chóng, không thay đổi giá trị và không có tác dụng phụ • Hàm này hoạt động theo cách tương tự như khi được gọi nhiều lần với cùng
một đối số và không sử dụng các giá trị khác như biến toàn cục hoặc lệnh gọi đến random()
• Hàm này mô tả giao diện người dùng mà không để lại bất kỳ tác dụng phụ nào, chẳng hạn như sửa đổi các thuộc tính hoặc biến toàn cục
Nhìn chung, bạn phải viết tất cả các hàm có khả năng kết hợp bằng các thuộc tính này vì những lý do được thảo luận trong phần kết hợp lại
4.3 Thay đổi mô hình khai báo
Với nhiều bộ công cụ giao diện người dùng hướng đối tượng bắt buộc, bạn khởi chạy giao diện người dùng bằng cách tạo một cây tiện ích Bạn thường thực hiện việc này bằng cách tăng cường một tệp bố cục XML Mỗi tiện ích duy trì một trạng thái nội bộ riêng và hiển thị các phương thức getter và setter cho phép logic ứng dụng tương tác với tiện ích đó
Trong phương pháp khai báo của Compose, các tiện ích tương đối không có trạng thái và không hiển thị các hàm setter hoặc getter Trên thực tế, các tiện ích không xuất hiện dưới dạng đối tượng Bạn cập nhật giao diện người dùng bằng cách gọi cùng một hàm có khả năng kết hợp với các đối số khác nhau Việc này giúp bạn dễ dàng cung cấp trạng thái cho các mẫu kiến trúc, chẳng hạn như ViewModel, như mô tả trong Hướng dẫn về cấu trúc ứng dụng Sau đó, các yếu tố có thể kết hợp sẽ chịu trách nhiệm chuyển đổi trạng thái ứng dụng hiện tại thành giao diện người dùng mỗi khi cập nhật dữ liệu có thể quan sát
Trang 16Hình 2: Logic của ứng dụng cung cấp dữ liệu cho hàm có khả năng kết hợp cấp
cao nhất Hàm đó sử dụng dữ liệu để mô tả giao diện người dùng bằng cách gọi các yếu tố có thể kết hợp khác và chuyển dữ liệu thích hợp cho các yếu tố có thể kết hợp đó và xuống hệ thống phân cấp
Khi người dùng tương tác với giao diện người dùng, giao diện người dùng sẽ
đưa ra các sự kiện như onClick Những sự kiện đó sẽ thông báo cho logic ứng
dụng, qua đó có thể thay đổi trạng thái của ứng dụng Khi trạng thái thay đổi, các hàm có khả năng kết hợp được gọi lại bằng dữ liệu mới Việc này khiến các thành phần trên giao diện người dùng được vẽ lại–quy trình này được gọi là
recomposition
Trang 17Hình 3 Người dùng tương tác với một thành phần trên giao diện người dùng,
khiến sự kiện được kích hoạt Logic của ứng dụng phản hồi sự kiện, sau đó các hàm có khả năng kết hợp sẽ tự động được gọi lại bằng các thông số mới (nếu cần)
4.4 Nội dung động
Vì các hàm có khả năng kết hợp được viết bằng Kotlin thay vì XML nên các hàm này có thể linh động như mọi mã Kotlin khác Ví dụ: giả sử bạn muốn tạo giao diện người dùng chào đón một danh sách người dùng:
Trang 184.5 Recomposition
Trong mô hình giao diện người dùng bắt buộc, để thay đổi một tiện ích, bạn phải gọi một phương thức setter trên tiện ích đó để thay đổi trạng thái nội bộ của phương thức đó Trong Compose, bạn gọi lại hàm có khả năng kết hợp với dữ liệu mới Cách làm này sẽ giúp vẽ lại hàm được kết hợp lại–các tiện ích do hàm cung cấp (nếu cần) cùng với dữ liệu mới Khung Compose có thể chỉ kết hợp lại các thành phần đã thay đổi một cách thông minh
Ví dụ: hãy xem xét hàm có khả năng kết hợp hiển thị một nút này:
Hình 5
Mỗi khi người dùng nhấp vào nút này, trình gọi sẽ cập nhật giá trị của clicks Compose gọi lambda bằng hàm Text để hiển thị giá trị mới; quy trình này được gọi là kết hợp lại Các hàm khác không phụ thuộc vào giá trị không được kết hợp lại
Như chúng ta đã thảo luận, việc kết hợp lại toàn bộ cây giao diện người dùng có thể sẽ tốn kém vì sẽ mất thêm công suất tính toán và thời lượng pin Compose giải quyết vấn đề này thông qua phương thức kết hợp lại thông minh sau
Kết hợp lại là quá trình gọi lại các hàm có khả năng kết hợp khi giá trị nhập thay đổi Quá trình này được thực hiện khi dữ liệu đầu vào của hàm thay đổi Khi Compose kết hợp lại dựa trên dữ liệu nhập mới, công cụ này chỉ gọi các hàm hoặc lambda có thể đã thay đổi và bỏ qua các yếu tố còn lại Bằng cách bỏ qua tất cả các hàm hoặc lambda không có thông số được thay đổi, Compose có thể kết hợp lại một cách hiệu quả
Không phụ thuộc vào tác dụng phụ của việc thực thi các hàm có khả năng kết hợp vì việc kết hợp lại một hàm có thể bị bỏ qua Nếu bạn thực hiện điều này, người dùng có thể gặp phải hành vi lạ và không thể đoán trước trong ứng dụng Tác dụng phụ là bất kỳ thay đổi nào hiển thị với phần còn lại của ứng dụng Ví dụ: những hành động sau đây đều là tác dụng phụ nguy hiểm:
• Ghi vào thuộc tính của đối tượng dùng chung • Cập nhật giá trị có thể quan sát trong ViewModel
Trang 19• Cập nhật các tuỳ chọn dùng chung
Các hàm có khả năng kết hợp có thể được thực thi lại thường xuyên trong mỗi khung hình, chẳng hạn như khi hệ thống hiển thị một ảnh động Các hàm có khả năng kết hợp phải nhanh chóng để tránh bị giật trong ảnh động Nếu bạn cần thực hiện các thao tác tốn kém, chẳng hạn như đọc từ các tuỳ chọn dùng chung, hãy thực hiện việc này trong coroutine trong nền và chuyển giá trị kết quả đến hàm có khả năng kết hợp dưới dạng thông số
Các phần sau đây sẽ trình bày cách tạo hàm có khả năng kết hợp để hỗ trợ quá trình kết hợp lại Trong mọi trường hợp, phương pháp hay nhất là đảm bảo các hàm có khả năng kết hợp chạy nhanh, không thay đổi giá trị và không có tác dụng phụ
4.5.1 Các hàm composable có thể thực thi theo thứ tự bất kỳ
Nếu kiểm tra mã cho một hàm có khả năng kết hợp, bạn có thể giả định rằng mã được chạy theo thứ tự nó xuất hiện Tuy nhiên, điều này không nhất thiết đúng Nếu một hàm có khả năng kết hợp chứa lệnh gọi đến các hàm có khả năng kết hợp khác thì các hàm đó có thể chạy theo thứ tự bất kỳ Bạn có thể dùng Compose để nhận diện một số thành phần trên giao diện người dùng có mức độ ưu tiên cao hơn các thành phần khác và vẽ ra các thành phần đó trước
Ví dụ: giả sử bạn có mã như sau để vẽ 3 màn hình trong một bố cục thẻ:
Các lệnh gọi đến StartScreen, MiddleScreen và EndScreen có thể xuất hiện theo thứ tự bất kỳ Điều này có nghĩa là bạn không thể để StartScreen() đặt một số
Trang 20chạy các hàm có khả năng kết hợp không có trên màn hình ở mức độ ưu tiên thấp hơn
Tính năng tối ưu hoá này có nghĩa là một hàm có khả năng kết hợp có thể thực thi trong một nhóm các chuỗi nền Nếu một hàm có khả năng kết hợp gọi một hàm trên ViewModel thì Compose có thể gọi hàm đó từ nhiều chuỗi cùng lúc
Để đảm bảo ứng dụng hoạt động chính xác, tất cả hàm có khả năng kết hợp không được có tác dụng phụ Thay vào đó, hãy kích hoạt các tác dụng phụ của lệnh gọi lại, chẳng hạn như onClick luôn thực thi trên chuỗi giao diện người dùng
Khi một hàm có khả năng kết hợp được gọi, lệnh gọi có thể xảy ra trên một chuỗi khác với phương thức gọi Điều đó có nghĩa là bạn nên tránh sử dụng mã sửa đổi các biến dưới dạng lambda có thể kết hợp vì loại mã này không an toàn cho chuỗi và vì đây là một tác dụng phụ không thể chấp nhận được của lambda có thể kết hợp
Sau đây là ví dụ về một composable cho thấy danh sách và số lượng:
Mã này không có tác dụng phụ và chuyển đổi danh sách nhập vào giao diện người dùng Đây là mã lý tưởng cho việc hiển thị một danh sách nhỏ Tuy nhiên, nếu hàm này ghi vào một biến cục bộ thì mã này sẽ không đúng hoặc không an toàn cho chuỗi:
Trang 21Ở ví dụ này, items được sửa đổi với các thành phần kết hợp lại Đó có thể là mọi khung ảnh động hoặc khi danh sách cập nhật Dù là điều nào thì giao diện người dùng cũng sẽ hiển thị số lượng không chính xác Do đó, cách ghi này sẽ không được hỗ trợ trong Compose, với việc cấm các cách ghi đó, chúng tôi cho phép khung thay đổi các chuỗi thực thi lambda có thể kết hợp
4.5.3 Bỏ qua recomposition nhiều nhất có thể
Khi các phần trong giao diện người dùng của bạn không hợp lệ, Compose sẽ cố gắng hết sức để kết hợp lại các phần cần cập nhật Điều này có nghĩa là công cụ này có thể bỏ qua để chạy lại thành phần có thể kết hợp của một nút mà không cần thực thi bất kỳ thao tác có thể kết hợp nào ở trên hoặc bên dưới trong cây giao diện người dùng
Mọi hàm và lambda có khả năng kết hợp đều có thể tự phân tích lại Sau đây là ví dụ minh họa cách việc kết hợp lại có thể bỏ qua một số phần tử khi hiển thị một danh sách:
Trang 22Mỗi phạm vi này có thể là nội dung duy nhất cần thực thi trong quá trình kết hợp lại Compose có thể bỏ qua cho đến lambda Column mà không cần thực thi bất kỳ yếu tố gốc nào của yếu tố này khi header thay đổi Và khi thực thi Column, Compose có thể chọn bỏ qua các mục của LazyColumn nếu names không thay đổi
Xin nhắc lại, việc thực thi tất cả hàm hoặc lambda có khả năng kết hợp không được có tác dụng phụ Khi bạn cần thực hiện tác dụng phụ, hãy kích hoạt từ lệnh gọi lại
4.5.4 Recomposition là khả quan
Việc kết hợp lại bắt đầu lại bất cứ khi nào Compose cho rằng các thông số của một thành phần có thể kết hợp có thể đã thay đổi Việc kết hợp lại là khả quan, nghĩa là Compose sẽ hoàn thành việc kết hợp lại trước khi các thông số thay đổi lần nữa
Trang 23Nếu một thông số thay đổi trước khi quá trình kết hợp lại hoàn tất thì Compose có thể sẽ hủy quá trình kết hợp lại đó và bắt đầu lại bằng thông số mới
Khi quá trình kết hợp lại bị hủy, Compose sẽ loại bỏ cây giao diện người dùng khỏi quá trình kết hợp lại Nếu bạn có bất kỳ tác dụng phụ nào phụ thuộc vào giao diện người dùng đang hiển thị thì tác dụng phụ này sẽ được áp dụng ngay cả khi quá trình kết hợp lại bị hủy Điều này có thể làm cho trạng thái ứng dụng không nhất quán
Hãy đảm bảo rằng tất cả hàm và lambda có khả năng kết hợp đều giống nhau và không có tác dụng phụ khi xử lý việc kết hợp lại một cách khả quan
4.5.5 Các hàm có khả năng recomposition có thể chạy khá thường xuyên
Trong một số trường hợp, một hàm có khả năng kết hợp có thể chạy cho mọi khung giao diện người dùng Nếu thực hiện các thao tác tốn kém (chẳng hạn như đọc từ bộ nhớ của thiết bị) thì hàm này có thể khiến giao diện người dùng bị giật
Ví dụ: nếu tiện ích cố gắng đọc chế độ cài đặt của thiết bị thì tiện ích đó có thể đọc chế độ cài đặt hàng trăm lần mỗi giây và gây ra ảnh hưởng tiêu cực đến hiệu suất của ứng dụng
Nếu hàm có khả năng kết hợp của bạn cần dữ liệu thì hàm đó phải xác định các thông số cho dữ liệu Sau đó, bạn có thể chuyển thao tác tốn kém sang một chuỗi khác, bên ngoài thành phần kết hợp và chuyển dữ liệu sang Compose bằng
mutableStateOf hoặc LiveData
5 Bố cục Compose cơ bản 5.1 Mục tiêu
Việc triển khai hệ thống bố cục trong Jetpack Compose có hai mục tiêu chính: • Hiệu suất cao
Trang 24Hàm có khả năng kết hợp là khối xây dựng cơ bản trong Compose Hàm có khả năng kết hợp là một hàm chèn Unit mô tả một số phần trên giao diện người dùng Hàm sử dụng một số dữ liệu đầu vào và tạo nội dung hiển thị trên màn hình Để biết thêm thông tin về các thành phần kết hợp, hãy xem tài liệu Mô hình tư duy của Compose
Một hàm có khả năng kết hợp có thể chuyển phát nhiều thành phần trên giao diện người dùng Tuy nhiên, nếu bạn không đưa ra cách sắp xếp, thì Compose có thể sắp xếp các thành phần theo cách mà bạn không muốn Ví dụ: mã này tạo ra hai thành phần văn bản:
Nếu bạn không hướng dẫn cách sắp xếp các thành phần này, thì công cụ Compose sẽ xếp chồng các thành phần văn bản lên nhau, khiến cho chúng không thể đọc được:
Compose cung cấp một tập hợp các bố cục sẵn sàng sử dụng để giúp bạn sắp xếp các thành phần trên giao diện người dùng và giúp bạn dễ dàng xác định các bố cục của riêng mình, ở mức độ chuyên biệt cao hơn
5.3 Các bố cục cơ bản
Trong nhiều trường hợp, bạn chỉ cần sử dụng Các thành phần của bố cục tiêu chuẩn trong Compose
Hãy dùng Column để đặt các mục theo chiều dọc trên màn hình
Trang 25Tương tự, hãy dùng Row để đặt các mục theo chiều ngang trên màn hình Cả hai mã Column và Row đều hỗ trợ định cấu hình căn chỉnh các thành phần có trong
mã
Sử dụng Box để xếp các thành phần chồng lên nhau Box cũng hỗ trợ định cấu
hình căn chỉnh cụ thể các thành phần có trong mã
Trang 26Thông thường, các khối xây dựng này là tất cả những gì bạn cần Bạn có thể viết hàm có khả năng kết hợp của riêng mình để kết hợp các bố cục này vào một bố cục chi tiết hơn phù hợp với ứng dụng của bạn
Lưu ý: Compose xử lý hiệu quả các bố cục lớp lồng nhau, khiến chúng trở
thành một cách tuyệt vời để thiết kế giao diện người dùng phức tạp Đây là một sự cải tiến so với Android Views, trong đó bạn cần tránh các bố cục lớp lồng ghép vì lý do hiệu suất
Để đặt vị trí bố cục con trong Row, hãy đặt các đối số horizontalArrangement và verticalAlignment Đối với Column, hãy đặt các đối số verticalArrangement và horizontalAlignment:
Trang 275.4 Mô hình bố cục
Trong mô hình bố cục, cây giao diện người dùng được sắp xếp chỉ trong một luồng Trước tiên, mỗi nút được yêu cầu tự đo lường, sau đó đo lường định kỳ bất cứ thành phần con cháu nào, chuyển các giới hạn kích thước xuống dọc theo cây cho các thành phần con cháu Sau đó, cần định kích thước và đặt các nút lá, rồi các kích cỡ đã được xác định cùng các câu lệnh hướng dẫn vị trí được chuyển trở lại cây
Tóm lại, cần đo lường các thành phần mẹ trước các thành phần con cháu, nhưng việc định kích thước và đặt các thành phần mẹ lại diễn ra sau các thành phần con cháu
Hãy xem xét hàm SearchResult sau
Trang 28Hàm này tạo cây giao diện người dùng sau đây
Trong ví dụ SearchResult, bố cục cây giao diện người dùng tuân theo thứ tự
sau:
1 Câu lệnh yêu cầu đo lường nút gốc Row
2 Nút gốc Row yêu cầu nút con cháu đầu tiên của nó, Image, đo lường 3 Image là một nút lá (nút không có nút con cháu), vì vậy nút này báo cáo
kích thước và trả về các câu lệnh hướng dẫn vị trí
4 Nút gốc Row yêu cầu nút con cháu thứ hai của nó, Column, đo lường 5 Nút Column yêu cầu nút con cháu đầu tiên của nó, Text, đo lường
6 Nút Text đầu tiên là một nút lá Nút lá chỉ báo cáo kích thước và trả về
câu lệnh hướng dẫn vị trí
7 Nút Column yêu cầu nút con cháu Text thứ hai của nó đo lường
8 Nút Text thứ hai là một nút lá, vì vậy nút này báo cáo kích thước và trả về
câu lệnh hướng dẫn vị trí
9 Hiện tại, nút Column đã đo lường xong, đã định kích thước và đặt các nút
con cháu của nó, nút này có thể xác định kích thước và vị trí của riêng mình
10 Hiện tại, nút gốc Row đã đo lường xong, đã định kích thước và đặt các
nút con cháu của nó, nút này có thể xác định kích thước và vị trí của riêng mình
Trang 295.5 Hiệu suất
Compose đạt được hiệu suất cao bằng cách đo lường nút con cháu một lần duy nhất Chế độ đo lường một luồng tốt cho hiệu suất, cho phép công cụ Compose xử lý sâu các cây giao diện người dùng một cách hiệu quả Nếu một thành phần đo lường thành phần con cháu của nó hai lần và thành phần con cháu đó đo lường từng thành phần con cháu của nó hai lần và cứ tiếp tục như vậy, thì một lần thử duy nhất để tạo ra toàn bộ Giao diện người dùng sẽ phải thực hiện rất nhiều việc, khiến ứng dụng của bạn khó duy trì hoạt động
Nếu bố cục của bạn cần nhiều lần đo lường vì một lý do nào đó, Compose có một hệ thống đặc biệt, phép đo lường hàm nội tại
Vì việc đo lường và vị trí là các giai đoạn phụ riêng biệt của luồng bố cục, nên các thay đổi chỉ ảnh hưởng đến vị trí của các mục mà không ảnh hưởng đến hoạt động đo lường, đều có thể được thực hiện riêng biệt
5.6 Sử dụng modifiers
Như đã đề cập ở phần các đối tượng sửa đổi trong Compose, bạn có thể sử dụng đối tượng sửa đổi để trang trí hoặc bổ sung các thành phần kết hợp của bạn Các đối tượng sửa đổi là thành phần cần thiết để tuỳ chỉnh bố cục của bạn Ví dụ: ở
đây chúng tôi liên kết một số đối tượng sửa đổi để tuỳ chỉnh ArtistCard:
Trang 30Trong mã trên, hãy chú ý đến các đối tượng sửa đổi có chức năng khác nhau được sử dụng cùng nhau
• clickable tạo một phản ứng kết hợp với thông tin do người dùng nhập và
hiển thị một hiệu ứng gợn sóng
• padding đặt khoảng trống quanh một thành phần
• fillMaxWidth làm cho thành phần kết hợp lấp đầy chiều rộng tối đa mà
thành phần mẹ đã cấp cho nó
• size() xác định chiều rộng và chiều cao ưu tiên của một thành phần
Lưu ý: Cùng với một số nội dung khác, đối tượng sửa đổi đóng vai trò tương
tự như vai trò của các thông số bố cục trong bố cục chế độ xem Tuy nhiên, vì đối tượng sửa đổi đôi khi theo phạm vi cụ thể, nên chúng cung cấp sự an toàn về loại cũng như giúp bạn khám phá và tìm hiểu nội dung có sẵn và phù hợp với một bố cục nhất định Với bố cục XML, đôi khi khó để biết liệu một thuộc tính bố cục cụ thể có áp dụng cho một chế độ xem nhất định hay không
Ngoài ra còn có các loại bố cục đặc biệt khác như Scrollable Layout, Reponsive Layout, Slot-base Layout không được đề cập trong tài liệu này
6 Quản lý trạng thái
Trang 31Trạng thái trong ứng dụng là giá trị bất kỳ có thể thay đổi theo thời gian Đây
là định nghĩa rất rộng và bao gồm mọi thứ từ cơ sở dữ liệu Room cho đến một biến
• Một bài đăng trên blog và các bình luận liên quan
• Ảnh động gợn sóng trên các nút phát khi người dùng nhấp vào • Hình dán mà người dùng có thể vẽ lên hình ảnh
Jetpack Compose giúp bạn hiểu rõ vị trí và cách thức lưu trữ cũng như dùng trạng thái trong một ứng dụng Android Tài liệu hướng dẫn này tập trung vào hoạt động kết nối giữa các trạng thái và thành phần kết hợp (composable), đồng thời tập trung vào những API mà Jetpack Compose cung cấp để xử lý trạng thái dễ dàng hơn
6.1 Trạng thái và composition
Compose mang tính khai báo và vì vậy, cách duy nhất để cập nhật Compose là gọi cùng một thành phần kết hợp (composable) với đối số mới Các đối số này là đại diện cho trạng thái giao diện người dùng Mỗi khi một trạng thái được cập nhật, một lượt tái cấu trúc (recomposition) diễn ra Do đó, những thành phần như TextField sẽ không tự động cập nhật như đối với khung hiển thị dựa trên XML bắt buộc Một thành phần kết hợp phải được thông báo rõ ràng về trạng thái mới để cập nhật tương ứng
Trang 32Nếu thực hiện việc này, bạn sẽ thấy rằng không có điều gì xảy ra Nguyên nhân là do TextField không tự cập nhật, mà sẽ cập nhật khi tham số value của nó thay đổi Lý do nằm ở cách hoạt động của tính năng cấu trúc (composition) và tái cấu trúc (recomposition) trong Compose
6.2 Trạng thái trong composition
Các hàm có khả năng kết hợp có thể sử dụng API remember để lưu trữ đối tượng trong bộ nhớ Một giá trị do remember tính toán được lưu trữ trong Cấu trúc (Composition) trong quá trình cấu trúc ban đầu Giá trị đã lưu trữ được trả về trong quá trình tái cấu trúc Bạn có thể dùng remember để lưu trữ cả đối tượng có thể thay đổi và không thể thay đổi
mutableStateOf tạo ra MutableState<T> có thể quan sát Đây là một loại đối
tượng có thể quan sát được tích hợp với thời gian chạy Compose
Mọi thay đổi đối với value sẽ lên lịch tái cấu trúc mọi hàm có khả năng kết hợp có thể đọc value Trong trường hợp ExpandingCard, bất cứ khi nào expanded thay đổi, hệ thống sẽ tái cấu trúc ExpandingCard
Có 3 cách để khai báo đối tượng MutableState trong một thành phần kết hợp:
• val mutableState = remember { mutableStateOf(default) } • var value by remember { mutableStateOf(default) }
Trang 33• val (value, setValue) = remember { mutableStateOf(default) }
Các thông tin khai báo này là tương đương và được cung cấp dưới dạng cú pháp dễ hiểu theo mục đích sử dụng của trạng thái Bạn nên chọn định dạng tạo ra mã dễ đọc nhất trong thành phần kết hợp mà bạn đang viết
Cú pháp uỷ quyền (delegate syntax) by yêu cầu các import sau:
Bạn có thể sử dụng giá trị đã ghi nhớ làm tham số cho các thành phần kết hợp khác hoặc thậm chí là logic trong các câu lệnh để thay đổi thành phần kết hợp được hiển thị Ví dụ: nếu bạn không muốn hiện lời chào nếu phần tên trống, hãy sử dụng
trạng thái trong câu lệnh if:
Mặc dù remember giúp bạn giữ lại trạng thái trên các lần tái cấu trúc, trạng
thái này sẽ không được giữ lại khi bạn thay đổi cấu hình Để làm được điều này,
Trang 34nó trở thành không trạng thái Mô hình chung để di chuyển trạng thái lên trên trong Jetpack Compose là thay thế biến trạng thái bằng 2 tham số:
• value: T: giá trị hiện tại để hiển thị
• onValueChange: (T) -> Unit: một sự kiện yêu cầu thay đổi giá trị này, trong đó T là giá trị mới được đề xuất
Tuy nhiên, bạn không bị giới hạn ở onValueChange Nếu các sự kiện cụ thể
hơn phù hợp với thành phần kết hợp, bạn nên xác định sự kiện bằng cách sử dụng
lambda như ExpandingCard với onExpand và onCollapse
Trạng thái được di chuyển lên trên theo cách này có một số thuộc tính quan trọng:
• Một nguồn đáng tin cậy (single source of truth): Bằng cách di chuyển trạng thái thay vì sao chép, chúng tôi đảm bảo rằng chỉ có một nguồn thông tin duy nhất Điều này giúp tránh các lỗi
• Được đóng gói (encapsulated): Chỉ các thành phần kết hợp có trạng thái mới có thể sửa đổi trạng thái của chúng Nó có tính nội bộ hoàn toàn • Có thể chia sẻ (shareable): Bạn có thể chia sẻ trạng thái được di chuyển
lên trên với nhiều thành phần kết hợp Nếu bạn muốn đọc name trong
một thành phần kết hợp khác, việc di chuyển trạng thái lên trên sẽ cho phép bạn làm việc đó
• Có thể chắn (interceptable): phương thức gọi đến các thành phần kết hợp không trạng thái có thể quyết định bỏ qua hoặc sửa đổi các sự kiện trước khi thay đổi trạng thái
• Được tách riêng (decoupled): trạng thái của ExpandingCard không có
trạng thái có thể được lưu trữ ở bất cứ đâu Ví dụ: bạn hiện có thể di
chuyển name sang ViewModel
Trong trường hợp ví dụ, bạn trích xuất name và onValueChange ra HelloContent rồi di chuyển chúng lên trên đến một thành phần kết hợp HelloScreen bằng lệnh gọi HelloContent
Trang 35Bằng cách nâng trạng thái ra khỏi HelloContent, sẽ dễ dàng cho việc lý giải thành phần kết hợp, tái sử dụng trong nhiều tình huống và kiểm thử HelloContent
được tách riêng khỏi cách lưu trữ trạng thái của tệp Việc tách riêng có nghĩa là nếu
sửa đổi hoặc thay thế HelloScreen, bạn không phải thay đổi cách thức triển khai HelloContent
Trang 36Mô hình mà trạng thái giảm và các sự kiện tăng lên được gọi là luồng dữ liệu một chiều (unidirectional) Trong trường hợp này, trạng thái giảm từ HelloScreen
xuống HelloContent và các sự kiện tăng từ HelloContent lên HelloScreen Bằng
cách làm theo luồng dữ liệu một chiều, bạn có thể phân tách các thành phần có thể kết hợp hiển thị trạng thái trong giao diện người dùng khỏi các phần của ứng dụng lưu trữ và thay đổi trạng thái
Lưu ý quan trọng: Khi chuyển trạng thái lên trên, có ba quy tắc giúp bạn tìm ra vị trí di chuyển trạng thái:
1 Trạng thái phải được di chuyển lên ít nhất đến trạng thái mẹ phổ biến thấp nhất trong tất cả thành phần kết hợp đang sử dụng trạng thái (đọc) 2 Trạng thái phải được di chuyển lên ít nhất đến cấp cao nhất mà nó có
thể được thay đổi (ghi)
3 Nếu 2 trạng thái thay đổi để phản hồi cùng một sự kiện, thì chúng phải được di chuyển lên trên cùng nhau
Bạn có thể chuyển trạng thái lên cao hơn so với yêu cầu trong các quy tắc này, nhưng trạng thái được chuyển lên trên không đúng mức sẽ làm cho việc đi theo luồng dữ liệu một chiều trở nên khó khăn hoặc bất khả thi
6.4 Khôi phục trạng thái
Sử dụng rememberSaveable để khôi phục trạng thái trên giao diện người dùng sau khi tái tạo một hoạt động hoặc quy trình rememberSaveable giữ lại trạng thái trên các quá trình tái cấu trúc Ngoài ra, rememberSaveable còn giữ nguyên trạng
thái trên quá trình tái tạo một hoạt động hoặc quy trình
Tất cả loại dữ liệu được thêm vào Bundle sẽ được lưu tự động Nếu muốn lưu nội dung nào đó mà không thể thêm vào Bundle, bạn có thể làm theo các cách sau:
Trang 376.4.2 MapSaver
Nếu vì lý do nào đó @Parcelize không phù hợp, bạn có thể sử dụng mapSaver để xác định quy tắc của riêng mình nhằm chuyển đổi một đối tượng thành một tập hợp giá trị mà hệ thống có thể lưu vào Bundle
6.5 Phần tử giữ trạng thái
Có thể quản lý quá trình chuyển trạng thái lên trên đơn giản trong chính các hàm có khả năng kết hợp Tuy nhiên, nếu số lượng trạng thái cần theo dõi tăng lên
Trang 38Ở đây, việc sử dụng hàm remember giúp giá trị MutableState vẫn tiếp tục có
hiệu lực khi kết hợp lại
Nói chung, remember nhận tham số lambda calculation Trong lần chạy đầu
tiên, remember sẽ gọi hàm lambda calculation và lưu trữ kết quả Trong quá trình
kết hợp lại, remember sẽ trả về giá trị được lưu trữ gần đây nhất
Ngoài trạng thái lưu vào bộ nhớ đệm, bạn cũng có thể sử dụng remember để
lưu trữ đối tượng bất kỳ hoặc kết quả của một thao tác trong Cấu trúc (Composition) nếu tốn kém khi khởi chạy hoặc tính toán Bạn có thể không muốn lặp lại phép tính này trong mỗi quá trình kết hợp lại Ví dụ như việc tạo đối tượng
ShaderBrush này có thể là một thao tác tốn kém:
remember lưu trữ giá trị cho đến khi thoát khỏi Cấu trúc Tuy nhiên, có một cách để vô hiệu hoá giá trị đã lưu vào bộ nhớ đệm API remember cũng lấy tham số
key hoặc keys Nếu bất kỳ khoá nào trong số này thay đổi thì lần tiếp theo khi hàm
kết hợp lại, remember sẽ vô hiệu hoá bộ nhớ đệm và thực thi lại khối lambda tính
toán Cơ chế này cho phép bạn kiểm soát toàn thời gian của một đối tượng trong Cấu trúc Phương pháp tính toán này vẫn có hiệu lực cho đến khi giá trị nhập thay đổi, thay vì cho đến khi giá trị được ghi nhớ bị xoá khỏi Cấu trúc
Các ví dụ sau đây minh hoạ cách hoạt động của cơ chế này
Trong đoạn mã này, ShaderBrush được tạo và sử dụng làm màu nền của thành phần kết hợp Box remember lưu trữ thực thể ShaderBrush vì việc tạo lại rất tốn kém, như chúng tôi đã giải thích trước đó remember lấy avatarRes làm tham số key1, là hình nền đã chọn Nếu avatarRes thay đổi, bút vẽ sẽ kết hợp lại với hình
Trang 39ảnh mới và áp dụng lại cho Box Điều này có thể xảy ra khi người dùng chọn một
hình ảnh khác trong bộ chọn làm hình nền
Trong đoạn mã tiếp theo, trạng thái được chuyển lên trên lớp phần tử giữ trạng
thái thuần tuý MyAppState Phương thức này hiển thị một hàm rememberMyAppState để khởi chạy một phiên bản của lớp bằng cách dùng remember Việc hiển thị các hàm như vậy để tạo phiên bản tiếp tục có hiệu lực
trong quá trình kết hợp lại là một mẫu phổ biến trong Compose Hàm
rememberMyAppState nhận windowSizeClass, đóng vai trò là tham số key cho remember Nếu tham số này thay đổi, ứng dụng cần tạo lại phần tử giữ trạng thái
thuần tuý có giá trị mới nhất Điều này có thể xảy ra nếu người dùng xoay thiết bị chẳng hạn
Compose sử dụng cách triển khai tương đương của lớp để quyết định xem một
Trang 40hợp Một thành phần Compose là cấu trúc dạng cây của các thành phần kết hợp mô tả Giao diện người dùng
Khi Jetpack Compose chạy các thành phần kết hợp lần đầu tiên, trong quá trình kết hợp ban đầu, bộ công cụ này sẽ theo dõi các thành phần kết hợp bạn gọi để mô tả Giao diện người dùng trong một thành phần Compose Sau đó, khi trạng thái ứng dụng thay đổi, Jetpack Compose sẽ lên lịch kết hợp lại Quá trình kết hợp lại xảy ra khi Jetpack Compose tái thực thi các thành phần kết hợp có thể thay đổi theo thay đổi về trạng thái, tiếp đến cập nhật thành phần Compose để phản ánh mọi thay đổi
Thành phần Compose chỉ có thể được quá trình kết hợp ban đầu tạo ra và cập nhật bằng quá trình kết hợp lại Phương pháp duy nhất để chỉnh sửa thành phần Compose là kết hợp lại
Hình 1 Vòng đời của một thành phần kết hợp trong thành phần Compose
Thành phần kết hợp này sẽ được nhập vào thành phần Compose, kết hợp lại từ 0 lần trở lên, cuối cùng ra khỏi thành phần Compose
Quá trình kết hợp lại thường được kích hoạt khi có thay đổi đối với đối tượng
State<T> Compose sẽ theo dõi quá trình thay đổi này, đồng thời chạy tất cả thành phần kết hợp trong thành phần Compose có khả năng đọc State<T> và bất kỳ thành
phần kết hợp quá trình này gọi mà không thể bỏ qua
Ngày đăng: 15/05/2024, 09:29
Xem thêm:
Từ khóa liên quan
Tài liệu cùng người dùng
Tài liệu liên quan