Lớp học lập trình này thuộc khoá học Kiến thức cơ bản về Kotlin cho Android. Bạn sẽ nhận được nhiều giá trị nhất qua khoá học này nếu thực hiện các lớp học lập trình theo trình tự. Tất cả lớp học lập trình của khoá học đều được liệt kê trên trang đích của lớp học lập trình Kiến thức cơ bản về cách tạo ứng dụng Android bằng Kotlin.
Giới thiệu
Lớp học lập trình này tóm tắt cách sử dụng kết hợp ViewModel
và các mảnh để triển khai hoạt động điều hướng. Hãy nhớ rằng mục tiêu là đặt logic của when để điều hướng vào ViewModel
, nhưng hãy xác định các đường dẫn trong các mảnh và tệp điều hướng. Để đạt được mục tiêu này, bạn sẽ sử dụng các mô hình khung hiển thị, mảnh, LiveData
và các đối tượng theo dõi.
Phần hướng dẫn này kết thúc bằng cách cho thấy một cách thông minh để theo dõi trạng thái nút với mã tối thiểu, sao cho mỗi nút chỉ được bật và có thể nhấp vào khi người dùng có thể nhấn vào nút đó.
Kiến thức bạn cần có
Bạn cần thông thạo:
- Xây dựng giao diện người dùng (UI) cơ bản bằng cách sử dụng một hoạt động, các mảnh và khung hiển thị.
- Điều hướng giữa các mảnh và sử dụng
safeArgs
để truyền dữ liệu giữa các mảnh. - Xem các mô hình, nhà máy mô hình hiển thị, các phép biến đổi và
LiveData
cũng như các đối tượng theo dõi của chúng. - Cách tạo cơ sở dữ liệu
Room
, tạo đối tượng truy cập dữ liệu (DAO) và xác định các thực thể. - Cách sử dụng coroutine cho các lượt tương tác với cơ sở dữ liệu và các tác vụ chạy trong thời gian dài khác.
Kiến thức bạn sẽ học được
- Cách cập nhật bản ghi hiện có về chất lượng giấc ngủ trong cơ sở dữ liệu.
- Cách sử dụng
LiveData
để theo dõi trạng thái của nút. - Cách hiển thị một thanh thông báo nhanh để phản hồi một sự kiện.
Bạn sẽ thực hiện
- Mở rộng ứng dụng TrackMySleepQuality để thu thập điểm xếp hạng chất lượng, thêm điểm xếp hạng vào cơ sở dữ liệu và hiển thị kết quả.
- Sử dụng
LiveData
để kích hoạt việc hiển thị một thanh thông báo nhanh. - Sử dụng
LiveData
để bật và tắt các nút.
Trong lớp học lập trình này, bạn sẽ tạo bản ghi chất lượng giấc ngủ và giao diện người dùng hoàn chỉnh của ứng dụng TrackMySleepQuality.
Ứng dụng này có 2 màn hình, được biểu thị bằng các mảnh, như minh hoạ trong hình bên dưới.
Màn hình đầu tiên (xuất hiện ở bên trái) có các nút để bắt đầu và dừng theo dõi. Màn hình này cho thấy tất cả dữ liệu về giấc ngủ của người dùng. Nút Xoá sẽ xoá vĩnh viễn tất cả dữ liệu mà ứng dụng đã thu thập cho người dùng.
Màn hình thứ hai (ở bên phải) là màn hình chọn mức đánh giá chất lượng giấc ngủ. Trong ứng dụng, điểm xếp hạng được biểu thị bằng số. Để phục vụ mục đích phát triển, ứng dụng này cho thấy cả biểu tượng khuôn mặt và giá trị tương đương bằng số của biểu tượng đó.
Luồng người dùng như sau:
- Người dùng mở ứng dụng và thấy màn hình theo dõi giấc ngủ.
- Người dùng nhấn vào nút Bắt đầu. Thao tác này sẽ ghi lại thời gian bắt đầu và hiển thị thời gian đó. Nút Start (Bắt đầu) bị vô hiệu hoá và nút Stop (Dừng) được bật.
- Người dùng nhấn vào nút Dừng. Thao tác này sẽ ghi lại thời gian kết thúc và mở màn hình chất lượng giấc ngủ.
- Người dùng chọn một biểu tượng chất lượng giấc ngủ. Màn hình đóng lại và màn hình theo dõi sẽ hiển thị thời gian kết thúc giấc ngủ và chất lượng giấc ngủ. Nút Stop (Dừng) bị tắt và nút Start (Bắt đầu) được bật. Ứng dụng đã sẵn sàng cho một đêm khác.
- Nút Xoá sẽ bật bất cứ khi nào có dữ liệu trong cơ sở dữ liệu. Khi người dùng nhấn vào nút Xoá, tất cả dữ liệu của họ sẽ bị xoá mà không có cách nào khôi phục được. Không có thông báo "Bạn có chắc chắn không?".
Ứng dụng này sử dụng một cấu trúc đơn giản, như minh hoạ dưới đây trong bối cảnh của cấu trúc đầy đủ. Ứng dụng chỉ sử dụng các thành phần sau:
- Bộ điều khiển giao diện người dùng
- Xem mô hình và
LiveData
- Cơ sở dữ liệu Room
Lớp học lập trình này giả định rằng bạn biết cách triển khai hoạt động điều hướng bằng cách sử dụng các mảnh và tệp điều hướng. Để giúp bạn tiết kiệm công sức, chúng tôi đã cung cấp một phần lớn mã này.
Bước 1: Kiểm tra mã
- Để bắt đầu, hãy tiếp tục với mã của riêng bạn từ cuối lớp học lập trình trước hoặc tải mã khởi đầu xuống.
- Trong mã khởi đầu, hãy kiểm tra
SleepQualityFragment
. Lớp này mở rộng bố cục, lấy ứng dụng và trả vềbinding.root
. - Mở navigation.xml trong trình chỉnh sửa thiết kế. Bạn thấy rằng có một đường dẫn điều hướng từ
SleepTrackerFragment
đếnSleepQualityFragment
và quay lại từSleepQualityFragment
đếnSleepTrackerFragment
. - Kiểm tra mã cho navigation.xml. Cụ thể, hãy tìm
<argument>
có tên làsleepNightKey
.
Khi người dùng chuyển từSleepTrackerFragment
sangSleepQualityFragment,
, ứng dụng sẽ truyền mộtsleepNightKey
đếnSleepQualityFragment
cho đêm cần được cập nhật.
Bước 2: Thêm chế độ điều hướng để theo dõi chất lượng giấc ngủ
Biểu đồ điều hướng đã bao gồm các đường dẫn từ SleepTrackerFragment
đến SleepQualityFragment
và ngược lại. Tuy nhiên, các trình xử lý lượt nhấp triển khai thao tác điều hướng từ một mảnh sang mảnh tiếp theo vẫn chưa được mã hoá. Bây giờ, bạn sẽ thêm mã đó vào ViewModel
.
Trong trình xử lý lượt nhấp, bạn đặt một LiveData
sẽ thay đổi khi bạn muốn ứng dụng chuyển đến một đích đến khác. Mảnh này theo dõi LiveData
. Khi dữ liệu thay đổi, mảnh sẽ chuyển đến đích đến và cho mô hình hiển thị biết rằng thao tác đã hoàn tất, thao tác này sẽ đặt lại biến trạng thái.
- Mở
SleepTrackerViewModel
. Bạn cần thêm chế độ điều hướng để khi người dùng nhấn vào nút Dừng, ứng dụng sẽ chuyển đếnSleepQualityFragment
để thu thập điểm chất lượng. - Trong
SleepTrackerViewModel
, hãy tạo mộtLiveData
thay đổi khi bạn muốn ứng dụng chuyển đếnSleepQualityFragment
. Sử dụng tính năng đóng gói để chỉ hiển thị phiên bản có thể nhận củaLiveData
choViewModel
.
Bạn có thể đặt mã này ở bất kỳ vị trí nào ở cấp cao nhất của nội dung lớp.
private val _navigateToSleepQuality = MutableLiveData<SleepNight>()
val navigateToSleepQuality: LiveData<SleepNight>
get() = _navigateToSleepQuality
- Thêm hàm
doneNavigating()
để đặt lại biến kích hoạt thao tác điều hướng.
fun doneNavigating() {
_navigateToSleepQuality.value = null
}
- Trong trình xử lý lượt nhấp cho nút Dừng,
onStopTracking()
, hãy kích hoạt thao tác điều hướng đếnSleepQualityFragment
. Đặt biến _navigateToSleepQuality
ở cuối hàm làm mục cuối cùng bên trong khốilaunch{}
. Xin lưu ý rằng biến này được đặt thànhnight
. Khi biến này có giá trị, ứng dụng sẽ chuyển đếnSleepQualityFragment
, truyền theo đêm.
_navigateToSleepQuality.value = oldNight
SleepTrackerFragment
cần theo dõinavigateToSleepQuality
để ứng dụng biết thời điểm điều hướng. TrongSleepTrackerFragment
, trongonCreateView()
, hãy thêm một đối tượng tiếp nhận dữ liệu chonavigateToSleepQuality()
. Xin lưu ý rằng quy trình nhập cho thành phần này không rõ ràng và bạn cần nhậpandroidx.lifecycle.Observer
.
sleepTrackerViewModel.navigateToSleepQuality.observe(this, Observer {
})
- Bên trong khối trình quan sát, hãy điều hướng và truyền mã nhận dạng của đêm hiện tại, rồi gọi
doneNavigating()
. Nếu nội dung nhập của bạn không rõ ràng, hãy nhậpandroidx.navigation.fragment.findNavController
.
night ->
night?.let {
this.findNavController().navigate(
SleepTrackerFragmentDirections
.actionSleepTrackerFragmentToSleepQualityFragment(night.nightId))
sleepTrackerViewModel.doneNavigating()
}
- Tạo bản dựng và chạy ứng dụng của bạn. Nhấn vào Start (Bắt đầu), sau đó nhấn vào Stop (Dừng) để chuyển đến màn hình
SleepQualityFragment
. Để quay lại, hãy dùng nút Quay lại của hệ thống.
Trong nhiệm vụ này, bạn sẽ ghi lại chất lượng giấc ngủ và quay lại mảnh trình theo dõi giấc ngủ. Màn hình sẽ tự động cập nhật để cho người dùng thấy giá trị mới. Bạn cần tạo một ViewModel
và một ViewModelFactory
, đồng thời cần cập nhật SleepQualityFragment
.
Bước 1: Tạo một ViewModel và một ViewModelFactory
- Trong gói
sleepquality
, hãy tạo hoặc mở SleepQualityViewModel.kt. - Tạo một lớp
SleepQualityViewModel
nhậnsleepNightKey
và cơ sở dữ liệu làm đối số. Giống như đối vớiSleepTrackerViewModel
, bạn cần truyềndatabase
từ nhà máy. Bạn cũng cần truyềnsleepNightKey
từ chế độ điều hướng.
class SleepQualityViewModel(
private val sleepNightKey: Long = 0L,
val database: SleepDatabaseDao) : ViewModel() {
}
- Bên trong lớp
SleepQualityViewModel
, hãy xác địnhJob
vàuiScope
, rồi ghi đèonCleared()
.
private val viewModelJob = Job()
private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)
override fun onCleared() {
super.onCleared()
viewModelJob.cancel()
}
- Để chuyển về
SleepTrackerFragment
bằng cách sử dụng cùng một mẫu như trên, hãy khai báo_navigateToSleepTracker
. Triển khainavigateToSleepTracker
vàdoneNavigating()
.
private val _navigateToSleepTracker = MutableLiveData<Boolean?>()
val navigateToSleepTracker: LiveData<Boolean?>
get() = _navigateToSleepTracker
fun doneNavigating() {
_navigateToSleepTracker.value = null
}
- Tạo một trình xử lý lượt nhấp,
onSetSleepQuality()
, để sử dụng cho tất cả hình ảnh về chất lượng giấc ngủ.
Sử dụng cùng một mẫu coroutine như trong lớp học lập trình trước:
- Khởi chạy một coroutine trong
uiScope
và chuyển sang trình điều phối I/O. - Nhận
tonight
bằngsleepNightKey
. - Đặt chất lượng giấc ngủ.
- Cập nhật cơ sở dữ liệu.
- Kích hoạt chế độ điều hướng.
Xin lưu ý rằng mẫu mã bên dưới thực hiện tất cả các thao tác trong trình xử lý lượt nhấp, thay vì tách thao tác cơ sở dữ liệu trong ngữ cảnh khác.
fun onSetSleepQuality(quality: Int) {
uiScope.launch {
// IO is a thread pool for running operations that access the disk, such as
// our Room database.
withContext(Dispatchers.IO) {
val tonight = database.get(sleepNightKey) ?: return@withContext
tonight.sleepQuality = quality
database.update(tonight)
}
// Setting this state variable to true will alert the observer and trigger navigation.
_navigateToSleepTracker.value = true
}
}
- Trong gói
sleepquality
, hãy tạo hoặc mởSleepQualityViewModelFactory.kt
rồi thêm lớpSleepQualityViewModelFactory
như minh hoạ bên dưới. Lớp này sử dụng một phiên bản của cùng một mã nguyên mẫu mà bạn đã từng thấy trước đây. Hãy kiểm tra mã trước khi chuyển sang bước tiếp theo.
class SleepQualityViewModelFactory(
private val sleepNightKey: Long,
private val dataSource: SleepDatabaseDao) : ViewModelProvider.Factory {
@Suppress("unchecked_cast")
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(SleepQualityViewModel::class.java)) {
return SleepQualityViewModel(sleepNightKey, dataSource) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
Bước 2: Cập nhật SleepQualityFragment
- Mở
SleepQualityFragment.kt
. - Trong
onCreateView()
, sau khi nhận đượcapplication
, bạn cần lấyarguments
đi kèm với chỉ đường. Các đối số này nằm trongSleepQualityFragmentArgs
. Bạn cần trích xuất các tệp này khỏi gói.
val arguments = SleepQualityFragmentArgs.fromBundle(arguments!!)
- Tiếp theo, hãy lấy
dataSource
.
val dataSource = SleepDatabase.getInstance(application).sleepDatabaseDao
- Tạo một nhà máy, truyền
dataSource
vàsleepNightKey
vào.
val viewModelFactory = SleepQualityViewModelFactory(arguments.sleepNightKey, dataSource)
- Tạo một tham chiếu
ViewModel
.
val sleepQualityViewModel =
ViewModelProviders.of(
this, viewModelFactory).get(SleepQualityViewModel::class.java)
- Thêm
ViewModel
vào đối tượng liên kết. (Nếu bạn thấy lỗi với đối tượng liên kết, hãy tạm thời bỏ qua lỗi đó.)
binding.sleepQualityViewModel = sleepQualityViewModel
- Thêm đối tượng tiếp nhận dữ liệu. Khi được nhắc, hãy nhập
androidx.lifecycle.Observer
.
sleepQualityViewModel.navigateToSleepTracker.observe(this, Observer {
if (it == true) { // Observed state is true.
this.findNavController().navigate(
SleepQualityFragmentDirections.actionSleepQualityFragmentToSleepTrackerFragment())
sleepQualityViewModel.doneNavigating()
}
})
Bước 3: Cập nhật tệp bố cục và chạy ứng dụng
- Mở tệp bố cục
fragment_sleep_quality.xml
. Trong khối<data>
, hãy thêm một biến choSleepQualityViewModel
.
<data>
<variable
name="sleepQualityViewModel"
type="com.example.android.trackmysleepquality.sleepquality.SleepQualityViewModel" />
</data>
- Đối với mỗi hình ảnh trong số 6 hình ảnh về chất lượng giấc ngủ, hãy thêm một trình xử lý lượt nhấp như trình xử lý bên dưới. Khớp mức chất lượng với hình ảnh.
android:onClick="@{() -> sleepQualityViewModel.onSetSleepQuality(5)}"
- Dọn dẹp và tạo lại dự án. Thao tác này sẽ giải quyết mọi lỗi với đối tượng liên kết. Nếu không, hãy xoá bộ nhớ đệm (File > Invalidate Caches / Restart (Tệp > Xoá bộ nhớ đệm/Khởi động lại)) rồi tạo lại ứng dụng.
Xin chúc mừng! Bạn vừa tạo một ứng dụng cơ sở dữ liệu Room
hoàn chỉnh bằng cách sử dụng coroutine.
Giờ đây, ứng dụng của bạn hoạt động rất tốt. Người dùng có thể nhấn vào Bắt đầu và Dừng bao nhiêu lần tuỳ thích. Khi người dùng nhấn vào Dừng, họ có thể nhập chất lượng giấc ngủ. Khi người dùng nhấn vào Xoá, tất cả dữ liệu sẽ được xoá âm thầm ở chế độ nền. Tuy nhiên, tất cả các nút luôn được bật và có thể nhấp vào, điều này không làm hỏng ứng dụng nhưng cho phép người dùng tạo các đêm ngủ không đầy đủ.
Trong nhiệm vụ cuối cùng này, bạn sẽ tìm hiểu cách sử dụng bản đồ biến đổi để quản lý khả năng hiển thị của nút, nhờ đó người dùng chỉ có thể đưa ra lựa chọn phù hợp. Bạn có thể sử dụng một phương thức tương tự để hiển thị một thông báo thân thiện sau khi xoá tất cả dữ liệu.
Bước 1: Cập nhật trạng thái nút
Ý tưởng là đặt trạng thái nút sao cho ban đầu, chỉ có nút Start (Bắt đầu) được bật, tức là có thể nhấp vào nút này.
Sau khi người dùng nhấn vào Start (Bắt đầu), nút Stop (Dừng) sẽ được bật và nút Start sẽ không được bật. Nút Xoá chỉ được bật khi có dữ liệu trong cơ sở dữ liệu.
- Mở tệp bố cục
fragment_sleep_tracker.xml
. - Thêm thuộc tính
android:enabled
vào mỗi nút. Thuộc tínhandroid:enabled
là một giá trị boolean cho biết nút có được bật hay không. (Bạn có thể nhấn vào nút đã bật; bạn không thể nhấn vào nút đã tắt.) Đặt giá trị của thuộc tính thành một biến trạng thái mà bạn sẽ xác định sau.
start_button
:
android:enabled="@{sleepTrackerViewModel.startButtonVisible}"
stop_button
:
android:enabled="@{sleepTrackerViewModel.stopButtonVisible}"
clear_button
:
android:enabled="@{sleepTrackerViewModel.clearButtonVisible}"
- Mở
SleepTrackerViewModel
và tạo 3 biến tương ứng. Chỉ định cho mỗi biến một phép biến đổi để kiểm thử biến đó.
- Nút Start (Bắt đầu) sẽ được bật khi
tonight
lànull
. - Nút Stop (Dừng) sẽ được bật khi
tonight
không phải lànull
. - Bạn chỉ nên bật nút Xoá nếu
nights
(và do đó là cơ sở dữ liệu) có chứa các đêm ngủ.
val startButtonVisible = Transformations.map(tonight) {
it == null
}
val stopButtonVisible = Transformations.map(tonight) {
it != null
}
val clearButtonVisible = Transformations.map(nights) {
it?.isNotEmpty()
}
- Chạy ứng dụng và thử nghiệm các nút.
Bước 2: Sử dụng thanh thông báo nhanh để thông báo cho người dùng
Sau khi người dùng xoá cơ sở dữ liệu, hãy cho người dùng thấy thông báo xác nhận bằng tiện ích Snackbar
. Thanh thông báo nhanh cung cấp thông tin phản hồi ngắn gọn về một thao tác thông qua một thông báo ở cuối màn hình. Snackbar sẽ biến mất sau một khoảng thời gian chờ, sau khi người dùng tương tác ở nơi khác trên màn hình hoặc sau khi người dùng vuốt snackbar ra khỏi màn hình.
Hiện thanh thông báo là một tác vụ giao diện người dùng và cần diễn ra trong mảnh. Quyết định hiển thị thanh thông báo nhanh trong ViewModel
. Để thiết lập và kích hoạt một thanh thông báo khi dữ liệu bị xoá, bạn có thể sử dụng cùng một kỹ thuật như khi kích hoạt thao tác điều hướng.
- Trong
SleepTrackerViewModel
, hãy tạo sự kiện được đóng gói.
private var _showSnackbarEvent = MutableLiveData<Boolean>()
val showSnackBarEvent: LiveData<Boolean>
get() = _showSnackbarEvent
- Sau đó, hãy triển khai
doneShowingSnackbar()
.
fun doneShowingSnackbar() {
_showSnackbarEvent.value = false
}
- Trong
SleepTrackerFragment
, trongonCreateView()
, hãy thêm một đối tượng tiếp nhận dữ liệu:
sleepTrackerViewModel.showSnackBarEvent.observe(this, Observer { })
- Bên trong khối trình quan sát, hãy hiển thị thanh thông báo và đặt lại sự kiện ngay lập tức.
if (it == true) { // Observed state is true.
Snackbar.make(
activity!!.findViewById(android.R.id.content),
getString(R.string.cleared_message),
Snackbar.LENGTH_SHORT // How long to display the message.
).show()
sleepTrackerViewModel.doneShowingSnackbar()
}
- Trong
SleepTrackerViewModel
, hãy kích hoạt sự kiện trong phương thứconClear()
. Để thực hiện việc này, hãy đặt giá trị sự kiện thànhtrue
bên trong khốilaunch
:
_showSnackbarEvent.value = true
- Tạo và chạy ứng dụng của bạn!
Dự án Android Studio: TrackMySleepQualityFinal
Việc triển khai tính năng theo dõi chất lượng giấc ngủ trong ứng dụng này giống như chơi một bản nhạc quen thuộc ở một khoá nhạc mới. Mặc dù các chi tiết có thay đổi, nhưng mẫu cơ bản của những việc bạn đã làm trong các lớp học lập trình trước đó trong bài học này vẫn giữ nguyên. Việc nhận biết những mẫu này giúp bạn lập trình nhanh hơn nhiều, vì bạn có thể sử dụng lại mã từ các ứng dụng hiện có. Sau đây là một số mẫu được sử dụng trong khoá học này cho đến nay:
- Tạo
ViewModel
vàViewModelFactory
, đồng thời thiết lập một nguồn dữ liệu. - Kích hoạt chế độ điều hướng. Để tách biệt các mối lo ngại, hãy đặt trình xử lý lượt nhấp trong mô hình thành phần hiển thị và thao tác điều hướng trong mảnh.
- Sử dụng tính năng đóng gói với
LiveData
để theo dõi và phản hồi các thay đổi về trạng thái. - Sử dụng các phép biến đổi với
LiveData
. - Tạo một cơ sở dữ liệu singleton.
- Thiết lập coroutine cho các thao tác với cơ sở dữ liệu.
Kích hoạt thao tác điều hướng
Bạn xác định các đường dẫn điều hướng có thể có giữa các mảnh trong một tệp điều hướng. Có một số cách khác nhau để kích hoạt thao tác điều hướng từ một mảnh này sang mảnh tiếp theo. bao gồm:
- Xác định trình xử lý
onClick
để kích hoạt thao tác điều hướng đến một mảnh đích. - Ngoài ra, để bật thao tác điều hướng từ một mảnh sang mảnh tiếp theo, hãy làm như sau:
- Xác định giá trị
LiveData
để ghi lại nếu thao tác điều hướng sẽ diễn ra. - Đính kèm một đối tượng tiếp nhận dữ liệu vào giá trị
LiveData
đó. - Sau đó, mã của bạn sẽ thay đổi giá trị đó bất cứ khi nào cần kích hoạt hoặc hoàn tất thao tác điều hướng.
Đặt thuộc tính android:enabled
- Thuộc tính
android:enabled
được xác định trongTextView
và được kế thừa bởi tất cả các lớp con, kể cảButton
. - Thuộc tính
android:enabled
xác định liệuView
có được bật hay không. Ý nghĩa của "đã bật" sẽ khác nhau tuỳ theo lớp con. Ví dụ:EditText
không được bật sẽ ngăn người dùng chỉnh sửa văn bản có trong đó vàButton
không được bật sẽ ngăn người dùng nhấn vào nút. - Thuộc tính
enabled
không giống với thuộc tínhvisibility
. - Bạn có thể sử dụng bảng chuyển đổi để đặt giá trị của thuộc tính
enabled
cho các nút dựa trên trạng thái của một đối tượng hoặc biến khác.
Các điểm khác được đề cập trong lớp học lập trình này:
- Để kích hoạt thông báo cho người dùng, bạn có thể sử dụng cùng một kỹ thuật như khi kích hoạt thao tác điều hướng.
- Bạn có thể dùng
Snackbar
để thông báo cho người dùng.
Khoá học của Udacity:
Tài liệu dành cho nhà phát triển Android:
Phần này liệt kê các bài tập về nhà cho học viên của lớp học lập trình này trong phạm vi khoá học có người hướng dẫn. Người hướng dẫn phải thực hiện các việc sau đây:
- Giao bài tập về nhà nếu cần.
- Trao đổi với học viên về cách nộp bài tập về nhà.
- Chấm điểm bài tập về nhà.
Người hướng dẫn có thể sử dụng các đề xuất này ít hoặc nhiều tuỳ ý và nên giao cho học viên bất kỳ bài tập về nhà nào khác mà họ cảm thấy phù hợp.
Nếu bạn đang tự học các lớp học lập trình, hãy sử dụng những bài tập về nhà này để kiểm tra kiến thức của mình.
Trả lời các câu hỏi sau
Câu hỏi 1
Một cách để cho phép ứng dụng của bạn kích hoạt thao tác điều hướng từ một mảnh này sang mảnh khác là sử dụng giá trị LiveData
để cho biết có kích hoạt thao tác điều hướng hay không.
Các bước để sử dụng giá trị LiveData
(gọi là gotoBlueFragment
) nhằm kích hoạt thao tác điều hướng từ mảnh màu đỏ đến mảnh màu xanh dương là gì? Hãy chọn tất cả các câu thích hợp:
- Trong
ViewModel
, hãy xác định giá trịLiveData
gotoBlueFragment
. - Trong
RedFragment
, hãy quan sát giá trịgotoBlueFragment
. Triển khai mãobserve{}
để chuyển đếnBlueFragment
khi thích hợp, sau đó đặt lại giá trị củagotoBlueFragment
để cho biết quá trình điều hướng đã hoàn tất. - Đảm bảo mã của bạn đặt biến
gotoBlueFragment
thành giá trị kích hoạt thao tác điều hướng bất cứ khi nào ứng dụng cần chuyển từRedFragment
sangBlueFragment
. - Đảm bảo mã của bạn xác định một trình xử lý
onClick
choView
mà người dùng nhấp vào để chuyển đếnBlueFragment
, trong đó trình xử lýonClick
sẽ quan sát giá trịgoToBlueFragment
.
Câu hỏi 2
Bạn có thể thay đổi trạng thái bật (có thể nhấp) hoặc tắt của một Button
bằng cách sử dụng LiveData
. Làm cách nào để bạn đảm bảo rằng ứng dụng của mình thay đổi nút UpdateNumber
sao cho:
- Nút này sẽ được bật nếu
myNumber
có giá trị lớn hơn 5. - Nút này sẽ không được bật nếu
myNumber
bằng hoặc nhỏ hơn 5.
Giả sử bố cục chứa nút UpdateNumber
bao gồm biến <data>
cho NumbersViewModel
như minh hoạ ở đây:
<data> <variable name="NumbersViewModel" type="com.example.android.numbersapp.NumbersViewModel" /> </data>
Giả sử mã nhận dạng của nút trong tệp bố cục là như sau:
android:id="@+id/update_number_button"
Bạn cần làm gì khác? Hãy chọn mọi câu trả lời phù hợp.
- Trong lớp
NumbersViewModel
, hãy xác định một biếnLiveData
làmyNumber
, đại diện cho số. Đồng thời, hãy xác định một biến có giá trị được đặt bằng cách gọiTransform.map()
trên biếnmyNumber
. Biến này sẽ trả về một giá trị boolean cho biết số đó có lớn hơn 5 hay không.
Cụ thể, trongViewModel
, hãy thêm mã sau:
val myNumber: LiveData<Int>
val enableUpdateNumberButton = Transformations.map(myNumber) {
myNumber > 5
}
- Trong bố cục XML, hãy đặt thuộc tính
android:enabled
củaupdate_number_button button
thànhNumberViewModel.enableUpdateNumbersButton
.
android:enabled="@{NumbersViewModel.enableUpdateNumberButton}"
- Trong
Fragment
sử dụng lớpNumbersViewModel
, hãy thêm một trình quan sát vào thuộc tínhenabled
của nút.
Cụ thể, trongFragment
, hãy thêm mã sau:
// Observer for the enabled attribute
viewModel.enabled.observe(this, Observer<Boolean> { isEnabled ->
myNumber > 5
})
- Trong tệp bố cục, hãy đặt thuộc tính
android:enabled
củaupdate_number_button button
thành"Observable"
.
Chuyển sang bài học tiếp theo:
Để biết đường liên kết đến các lớp học lập trình khác trong khoá học này, hãy xem trang đích của lớp học lập trình Kiến thức cơ bản về cách tạo ứng dụng Android bằng Kotlin.