1. Trước khi bắt đầu
Các thiết bị Android có nhiều hình dạng và kích thước. Do đó, bạn cần thiết lập bố cục của ứng dụng theo kích thước màn hình để cung cấp cho mọi người dùng và thiết bị thông qua một Gói Android (APK) hoặc Android App Bundle (AAB). Để thực thi mục tiêu đó, bạn cần xác định ứng dụng bằng bố cục thích ứng và phản hồi, thay vì xác định ứng dụng bằng các kích thước tĩnh giả định kích thước màn hình và tỷ lệ khung hình nhất định. Bố cục thích ứng thay đổi dựa trên không gian màn hình có sẵn.
Lớp học lập trình này hướng dẫn cho bạn những nội dung cơ bản về cách tạo giao diện người dùng thích ứng, đồng thời điều chỉnh ứng dụng để hiện danh sách và thông tin chi tiết các môn thể thao để hỗ trợ các thiết bị có màn hình lớn. Ứng dụng thể thao gồm ba màn hình: trang chính, kênh yêu thích và chế độ cài đặt. Trên màn hình chính, bạn sẽ thấy danh sách các môn thể thao và một phần giữ chỗ cho tin tức khi bạn chọn một môn thể thao từ danh sách. Màn hình mục yêu thích và cài đặt cũng hiển thị phần giữ chỗ cho văn bản. Bạn sẽ chọn mục liên kết trong trình đơn điều hướng dưới cùng để chuyển đổi giữa các màn hình.
Ứng dụng bắt đầu với những vấn đề về bố cục trên màn hình lớn:
- Bạn không thể dùng chế độ này theo hướng dọc.
- Nó hiển thị quá nhiều không gian trống trên màn hình lớn.
- Nó luôn hiển thị trình đơn điều hướng dưới cùng trên màn hình lớn.
Bạn làm cho ứng dụng trở nên thích ứng để:
- Hỗ trợ cả hướng ngang và hướng dọc.
- Hiển thị danh sách các môn thể thao và tin tức về từng môn thể thao cạnh nhau khi có đủ không gian hàng ngang để thực hiện.
- Hiển thị thành phần điều hướng theo nguyên tắc của Material Design.
Đây là ứng dụng một hoạt động duy nhất có một số mảnh. Bạn sẽ làm việc với các tệp sau:
- Tệp
AndroidManifest.xml
cung cấp siêu dữ liệu về ứng dụng thể thao. - Tệp
MainActivity.kt
, chứa mã được tạo bằng tệpactivity_main.xml
, chú thíchoverride
, lớpenum
đại diện cho kích thước lớp chiều rộng và định nghĩa phương thức để truy xuất chiều rộng lớp kích thước cửa sổ của cửa sổ ứng dụng. Trình đơn điều hướng dưới cùng sẽ được khởi chạy khi tạo hoạt động. - Tệp
activity_main.xml
xác định bố cục mặc định của hoạt độngMain
. - Tệp
layout-sw600dp/activity_main.xml
xác định bố cục thay thế cho hoạt độngMain
. Bố cục thay thế có hiệu lực khi chiều rộng cửa sổ của ứng dụng lớn hơn hoặc bằng giá trị600dp
. Nội dung giống với bố cục mặc định tại điểm bắt đầu. - Tệp
SportsListFragment.kt
chứa nội dung triển khai danh sách các môn thể thao và điều hướng quay lại tuỳ chỉnh. - Tệp
fragment_sports_list.xml
xác định bố cục của danh sách các môn thể thao. - Tệp
navigation_menu.xml
xác định các mục trong trình đơn điều hướng ở dưới cùng.
Hình 1. Ứng dụng thể thao hỗ trợ nhiều kích thước cửa sổ bằng một gói APK hoặc AAB.
Điều kiện tiên quyết
- Có kiến thức cơ bản về cách phát triển giao diện người dùng dựa trên chế độ xem
- Có kinh nghiệm về cú pháp Kotlin, bao gồm cả hàm lambda
- Đã hoàn thành lớp học lập trình cơ bản về Jetpack Compose
Kiến thức bạn sẽ học được
- Cách hỗ trợ thay đổi cấu hình.
- Cách thêm bố cục thay thế ít phải sửa đổi mã hơn.
- Cách triển khai giao diện người dùng chi tiết theo danh sách, hoạt động theo cách khác nhau cho các kích thước cửa sổ khác nhau.
Sản phẩm bạn sẽ tạo ra
Một ứng dụng Android hỗ trợ:
- Thiết bị xoay ngang
- Máy tính bảng, máy tính để bàn và thiết bị di động
- Danh sách chi tiết hành vi cho các kích thước màn hình khác nhau
Bạn cần có
- Android Studio Bumblebee | 2021.1.1 trở lên
- Một máy tính bảng hoặc trình mô phỏng Android
2. Bắt đầu thiết lập
Tải mã xuống cho lớp học lập trình này và thiết lập dự án:
- Từ dòng lệnh, hãy sao chép mã trong kho lưu trữ GitHub:
$ git clone https://github.com/android/add-adaptive-layouts
- Trong Android Studio, hãy mở dự án
AddingAdaptiveLayout
. Dự án được xây dựng trong nhiều nhánh git.
- Nhánh
main
chứa mã khởi đầu cho dự án này. Bạn thực hiện các thay đổi đối với nhánh này để hoàn tất lớp học lập trình. - Nhánh
end
chứa giải pháp cho lớp học lập trình này.
3. Di chuyển thành phần điều hướng trên cùng vào Compose
Ứng dụng thể thao sử dụng trình đơn điều hướng dưới cùng làm thành phần điều hướng trên cùng. Thành phần điều hướng này được triển khai bằng lớp BottomNavigationView
. Trong phần này, bạn sẽ di chuyển thành phần điều hướng trên cùng sang Compose.
Trình bày nội dung của tài nguyên trình đơn liên kết dưới dạng một lớp kín
- Tạo một lớp kín
MenuItem
để trình bày nội dung của tệpnavigation_menu.xml
, sau đó truyền cho nó một tham sốiconId
, một tham sốlabelId
và một tham sốdestinationId
. - Thêm một đối tượng
Home
, một đối tượngFavorite
và một đối tượngSettings
dưới dạng lớp con tương ứng với nơi đến.
MenuItem.kt
sealed class MenuItem(
// Resource ID of the icon for the menu item
@DrawableRes val iconId: Int,
// Resource ID of the label text for the menu item
@StringRes val labelId: Int,
// ID of a destination to navigate users
@IdRes val destinationId: Int
) {
object Home: MenuItem(
R.drawable.ic_baseline_home_24,
R.string.home,
R.id.SportsListFragment
)
object Favorites: MenuItem(
R.drawable.ic_baseline_favorite_24,
R.string.favorites,
R.id.FavoritesFragment
)
object Settings: MenuItem(
R.drawable.ic_baseline_settings_24,
R.string.settings,
R.id.SettingsFragment
)
}
Triển khai trình đơn điều hướng dưới cùng ở dạng hàm kết hợp
- Xác định một hàm kết hợp
BottomNavigationBar
nhận 3 tham số sau: một đối tượngmenuItems
được đặt thành giá trịList<MenuItem>
, một đối tượngmodifier
được đặt thành giá trịModifier = Modifier
và một đối tượngonMenuSelected
được đặt thành hàm lambda(MenuItem) -> Unit = {}
. - Trong phần nội dung của hàm kết hợp
BottomNavigationBar
, hãy gọi hàmNavigationBar()
để nhận tham sốmodifier
. - Trong hàm lambda được truyền vào hàm
NavigationBar()
, hãy gọi phương thứcforEach()
trên tham sốmenuItems
, sau đó gọi một hàmNavigationBarItem()
trong hàm lambda được đặt thành lệnh gọi phương thứcforeach()
. - Truyền cho hàm
NavigationBarItem()
một tham sốselected
được đặt thành giá trịfalse
, một tham sốonClick
được đặt thành hàm lambda chứa hàmonMenuSelected
có tham sốMenuItem
, một tham sốicon
được đặt thành hàm lambda chứa hàmIcon
lấy tham sốpainter = painterResource(id = menuItem.iconId)
và tham sốcontentDescription = null
cùng tham sốlabel
được đặt thành hàm lambda chứa hàmText
lấy tham số(text = stringResource(id = menuItem.labelId)
.
Navigation.kt
@Composable
fun BottomNavigationBar(
menuItems: List<MenuItem>,
modifier: Modifier = Modifier,
onMenuSelected: (MenuItem) -> Unit = {}
) {
NavigationBar(modifier = modifier) {
menuItems.forEach { menuItem ->
NavigationBarItem(
selected = false,
onClick = { onMenuSelected(menuItem) },
icon = {
Icon(
painter = painterResource(id = menuItem.iconId),
contentDescription = null)
},
label = { Text(text = stringResource(id = menuItem.labelId))}
)
}
}
}
Thay thế phần tử BottomNavigationView
bằng phần tử ComposeView
trong tệp tài nguyên bố cục
- Trong tệp
activity_main.xml
, hãy thay thế phần tửBottomNavigationView
bằng phần tửComposeView
. Thao tác này sẽ nhúng thành phần điều hướng dưới cùng vào một bố cục giao diện người dùng dựa trên chế độ xem bằng tính năng Compose.
activity_main.xml
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment_content_main"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@id/top_navigation"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav_graph" />
<androidx.compose.ui.platform.ComposeView
android:id="@+id/navigation"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/top_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
Tích hợp trình đơn điều hướng dưới cùng dựa trên Compose với bố cục giao diện người dùng dựa trên chế độ xem
- Trong tệp
MainActivity.kt
, hãy xác định một biếnnavigationMenuItems
được đặt thành danh sách các đối tượngMenuItem
. Các đối tượngMenuItems
sẽ xuất hiện trong trình đơn điều hướng dưới cùng theo thứ tự danh sách. - Gọi hàm
BottomNavigationBar()
để nhúng trình đơn điều hướng dưới cùng vào đối tượngComposeView
. - Chuyển đến đích đến liên kết với mục do người dùng chọn trong hàm callback được truyền vào hàm
BottomNavigationBar
.
MainActivity.kt
val navigationMenuItems = listOf(
MenuItem.Home,
MenuItem.Favorites,
MenuItem.Settings
)
binding.navigation.setContent {
MaterialTheme {
BottomNavigationBar(menuItems = navigationMenuItems){ menuItem ->
navController.navigate(screen.destinationId)
}
}
}
4. Hỗ trợ hướng ngang
Nếu ứng dụng của bạn hỗ trợ thiết bị màn hình lớn, nó được kỳ vọng sẽ hỗ trợ cả hướng ngang và dọc. Hiện tại, ứng dụng của bạn chỉ có một hoạt động: hoạt động trên MainActivity
.
Hướng hiển thị của hoạt động trên thiết bị được đặt trong tệp AndroidManifest.xml
có thuộc tính android:screenOrientation
, được đặt thành giá trị portrait
.
Cách tạo ứng dụng hỗ trợ theo hướng ngang
- Đặt thuộc tính
android:screenOrientation
thành giá trịfullUser
. Với cấu hình này, người dùng có thể khoá hướng màn hình. Hướng được xác định bằng cảm biến hướng thiết bị cho một trong bốn hướng.
AndroidManifest.xml
<activity
android:name=".MainActivity"
android:exported="true"
android:screenOrientation="fullUser">
Hình 2. Ứng dụng sẽ chạy theo hướng ngang sau khi bạn cập nhật tệp AndroidManifest.xml
.
5. Lớp kích thước cửa sổ
Đây là các giá trị điểm ngắt giúp phân loại kích thước cửa sổ thành các lớp kích thước được xác định trước: nhỏ gọn, trung bình và mở rộng, với kích thước cửa sổ thô có sẵn cho ứng dụng. Bạn sẽ dùng các lớp kích thước này khi thiết kế, phát triển và thử nghiệm bố cục thích ứng.
Chiều rộng và chiều cao có sẵn được phân vùng độc lập để ứng dụng luôn liên kết với hai lớp kích thước cửa sổ: lớp kích thước cửa sổ chiều rộng và lớp kích thước cửa sổ chiều cao.
Hình 3. Các lớp có kích thước cửa sổ theo chiều rộng và các điểm ngắt được liên kết.
Hình 4. Các lớp có kích thước cửa sổ theo chiều cao và điểm ngắt liên kết.
Các lớp kích thước cửa sổ thể hiện kích thước cửa sổ hiện tại của ứng dụng. Nói cách khác, bạn không thể xác định lớp kích thước cửa sổ theo kích thước thiết bị thực tế. Ngay cả khi ứng dụng của bạn chạy trên cùng một thiết bị, lớp kích thước cửa sổ được liên kết vẫn thay đổi theo cấu hình, chẳng hạn như khi bạn chạy ứng dụng ở chế độ chia đôi màn hình. Điều này có hai hệ quả quan trọng:
- Thiết bị thực tế không đảm bảo một lớp có kích thước cửa sổ cụ thể.
- Lớp kích thước cửa sổ có thể thay đổi trong suốt thời gian hoạt động của ứng dụng.
Sau khi thêm bố cục thích ứng vào ứng dụng, bạn sẽ thử nghiệm ứng dụng trên tất cả các kích thước cửa sổ, đặc biệt là trên các lớp có kích thước cửa sổ nhỏ, trung bình và mở rộng. Việc kiểm tra cho từng lớp kích thước cửa sổ là cần thiết, nhưng không đủ trong nhiều trường hợp. Điều quan trọng là bạn phải thử nghiệm ứng dụng trên nhiều kích thước cửa sổ để có thể đảm bảo giao diện người dùng điều chỉnh đúng cách. Để biết thêm thông tin, hãy xem phần Bố cục màn hình lớn và Chất lượng ứng dụng trên màn hình lớn.
6. Giới thiệu các ngăn danh sách và chi tiết cạnh nhau trên màn hình lớn
Một danh sách chi tiết giao diện người dùng có thể cần hoạt động khác nhau theo lớp kích thước cửa sổ theo chiều rộng hiện tại. Khi lớp kích thước cửa sổ theo chiều rộng trung bình hoặc mở rộng được liên kết với ứng dụng, có nghĩa là ứng dụng có thể có đủ không gian để hiện ngăn danh sách và ngăn chi tiết cạnh nhau, nhờ đó người dùng có thể xem danh sách các mục và thông tin chi tiết mục đã chọn mà không cần phải chuyển đổi màn hình. Tuy nhiên, nếu hiện theo cách này thì các màn hình nhỏ có thể trở nên quá chật chội, do đó tốt hơn nên hiện từng ngăn một với ngăn danh sách được hiện ban đầu. Ngăn chi tiết hiển thị thông tin chi tiết về mục đã chọn khi người dùng nhấn vào một mục trong danh sách. Lớp SlidingPaneLayout
quản lý logic để xác định trải nghiệm người dùng nào trong số hai trải nghiệm người dùng này phù hợp với kích thước cửa sổ hiện tại.
Định cấu hình bố cục ngăn danh sách
Lớp SlidingPaneLayout
là thành phần giao diện người dùng dựa trên chế độ xem. Bạn sửa đổi tệp tài nguyên bố cục cho ngăn danh sách, đó là tệp fragment_sports_list.xml
trong lớp học lập trình này.
Lớp SlidingPaneLayout
có 2 phần tử con. Thuộc tính chiều rộng và trọng số của từng phần tử con là các yếu tố chính cho lớp SlidingPaneLayout
để xác định xem cửa sổ có đủ lớn để hiển thị cả hai chế độ xem cạnh nhau hay không. Nếu không, danh sách toàn màn hình sẽ được thay thế bằng giao diện người dùng toàn màn hình. Giá trị trọng số được gọi là kích thước hai ngăn theo tỷ lệ khi cửa sổ có kích thước lớn hơn yêu cầu tối thiểu để hiện các ngăn cạnh nhau.
Lớp SlidingPaneLayout
đã được áp dụng cho tệp fragment_sports_list.xml
. Ngăn danh sách được định cấu hình để có chiều rộng là 1280dp
. Đây là lý do khiến ngăn danh sách và thông tin chi tiết không hiển thị cạnh nhau.
Cách làm cho các ngăn hiển thị cạnh nhau khi màn hình lớn hơn 580dp
chiều rộng:
- Đặt
RecyclerView
thành280dp
chiều rộng.
fragment_sports_list.xml
<androidx.slidingpanelayout.widget.SlidingPaneLayout
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:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SportsListFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="280dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:clipToPadding="false"
android:padding="8dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
<androidx.fragment.app.FragmentContainerView
android:layout_height="match_parent"
android:layout_width="300dp"
android:layout_weight="1"
android:id="@+id/detail_container"
android:name="com.example.android.sports.NewsDetailsFragment"/>
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
Hình 5. Danh sách và ngăn chi tiết hiển thị cạnh nhau sau khi bạn cập nhật tệp tài nguyên bố cục.
Hoán đổi ngăn chi tiết
Lúc này, ngăn danh sách và thông tin chi tiết hiện cạnh nhau khi lớp kích thước cửa sổ có chiều rộng trung bình hoặc mở rộng được liên kết với ứng dụng. Tuy nhiên, sẽ xảy ra trường hợp màn hình chuyển đổi hoàn toàn sang ngăn chi tiết khi người dùng chọn một mục từ ngăn danh sách.
Hình 6. Màn hình sẽ chuyển sang ngăn chi tiết sau khi bạn chọn một môn thể thao từ danh sách.
Vấn đề này là do việc di chuyển được kích hoạt khi người dùng chọn một mục trong ngăn danh sách. Mã liên quan có trong tệp SportsListFragment.kt
.
SportsListFragment.kt
val adapter = SportsAdapter {
sportsViewModel.updateCurrentSport(it)
// Navigate to the details pane.
val action =
SportsListFragmentDirections.actionSportsListFragmentToNewsFragment()
this.findNavController().navigate(action)
}
Đảm bảo việc màn hình chỉ chuyển hoàn toàn sang ngăn chi tiết khi không có đủ chỗ để hiển thị danh sách và ngăn chi tiết cạnh nhau:
- Trong biến hàm
adapter
, hãy thêm một câu lệnhif
để kiểm tra xem thuộc tínhisSlidable
của lớpSlidingPaneLayout
có đúng hay không và thuộc tínhisOpen
của lớpSlidingPaneLayout
có phải là false.
SportsListFragment.kt
val adapter = SportsAdapter {
sportsViewModel.updateCurrentSport(it)
if(slidingPaneLayout.isSlidable && !slidingPaneLayout.isOpen){
// Navigate to the details pane.
val action =
SportsListFragmentDirections.actionSportsListFragmentToNewsFragment()
this.findNavController().navigate(action)
}
}
7. Chọn đúng thành phần điều hướng theo lớp kích thước cửa sổ theo chiều rộng
Material Design muốn ứng dụng của bạn chọn các thành phần có tính thích ứng. Trong phần này, bạn chọn thành phần điều hướng cho thanh điều hướng trên cùng dựa trên lớp kích thước cửa sổ theo chiều rộng hiện tại. Bảng này mô tả thành phần điều hướng dự kiến cho mỗi lớp kích thước cửa sổ:
Lớp kích thước cửa sổ theo chiều rộng | Thành phần điều hướng |
Nhỏ | Thanh điều hướng dưới cùng |
Trung bình | Dải điều hướng |
Mở rộng | Ngăn điều hướng cố định |
Triển khai dải điều hướng
- Tạo một hàm kết hợp
NavRail()
, nhận 3 tham số: một đối tượngmenuItems
được đặt thành một giá trịList<MenuItem>
, một đối tượngmodifier
được đặt thành một giá trịModifier
và một hàm lambdaonMenuSelected
. - Trong phần nội dung hàm, hãy gọi một hàm
NavigationRail()
lấy đối tượngmodifier
làm tham số. - Gọi hàm
NavigationRailItem()
cho mỗi đối tượngMenuItem
trong đối tượngmenuItems
như đối với hàmNavigationBarItem
trong hàmBottomNavigationBar()
.
Triển khai ngăn điều hướng cố định
- Tạo một hàm kết hợp
NavigationDrawer()
, lấy 3 tham số sau: một đối tượngmenuItems
được đặt thành giá trịList<MenuItem>
, một đối tượngmodifier
được đặt thành giá trịModifier
và một hàm lambdaonMenuSelected
. - Trong phần nội dung hàm, hãy gọi một hàm
Column()
nhận đối tượngmodifier
làm tham số. - Gọi một hàm
Row()
cho từng đối tượngMenuItem
trong đối tượngmenuItems
. - Trong phần nội dung của hàm
Row()
, hãy thêm các nhãnicon
vàtext
giống như bạn đã làm với hàmNavigationBarItem
trong hàmBottomNavigationBar()
.
Chọn đúng thành phần điều hướng theo lớp kích thước chiều rộng cửa sổ
- Để truy xuất lớp kích thước cửa sổ theo chiều rộng hiện tại, hãy gọi hàm
rememberWidthSizeClass()
bên trong hàm kết hợp được truyền đến phương thứcsetContent()
trên đối tượngComposeView
. - Tạo nhánh có điều kiện để chọn thành phần điều hướng dựa trên lớp kích thước cửa sổ theo chiều rộng được truy xuất và gọi thành phần đã chọn.
- Truyền một đối tượng
Modifier
cho hàmNavigationDrawer
để chỉ định chiều rộng của đối tượng này làm giá trị256dp
.
ActivityMain.kt
binding.navigation.setContent {
MaterialTheme {
when(rememberWidthSizeClass()){
WidthSizeClass.COMPACT ->
BottomNavigationBar(menuItems = navigationMenuItems){ menuItem ->
navController.navigate(screen.destinationId)
}
WidthSizeClass.MEDIUM ->
NavRail(menuItems = navigationMenuItems){ menuItem ->
navController.navigate(screen.destinationId)
}
WidthSizeClass.EXPANDED ->
NavigationDrawer(
menuItems = navigationMenuItems,
modifier = Modifier.width(256.dp)
) { menuItem ->
navController.navigate(screen.destinationId)
}
}
}
}
Đặt thành phần điều hướng ở vị trí thích hợp
Bây giờ, ứng dụng của bạn có thể chọn đúng thành phần điều hướng dựa trên lớp kích thước cửa sổ theo chiều rộng hiện tại, nhưng bạn không thể đặt các thành phần đã chọn như mong đợi. Điều này là do phần tử ComposeView
được đặt trong phần tử FragmentViewContainer
.
Cập nhật tài nguyên bố cục thay thế cho lớp MainActivity
:
- Mở tệp
layout-sw600dp/activity_main.xml
. - Cập nhật quy tắc ràng buộc để bố trí phần tử
ComposeView
và phần tửFragmentContainer
theo chiều ngang.
layout-sw600dp/activity_main.xml
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment_content_main"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintLeft_toRightOf="@+id/top_navigation"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:navGraph="@navigation/nav_graph" />
<androidx.compose.ui.platform.ComposeView
android:id="@+id/top_navigation"
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/top_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
Sau khi sửa đổi, ứng dụng sẽ chọn đúng thành phần điều hướng dựa trên lớp kích thước cửa sổ theo chiều rộng tương ứng. Ảnh chụp màn hình đầu tiên hiện màn hình của lớp kích thước cửa sổ theo chiều rộng trung bình. Ảnh chụp màn hình thứ hai hiển thị màn hình của lớp kích thước cửa sổ theo chiều rộng mở rộng.
Hình 7. Màn hình cho các lớp kích thước cửa sổ theo chiều rộng trung bình và mở rộng.
8. Xin chúc mừng
Xin chúc mừng! Bạn đã hoàn thành lớp học lập trình này và đã biết cách dùng Compose để thêm bố cục thích ứng vào ứng dụng Android dựa trên khung hiển thị. Trong quá trình học, bạn cũng được tìm hiểu về lớp SlidingPaneLayout
, lớp kích thước cửa sổ và lựa chọn thành phần điều hướng dựa trên lớp kích thước cửa sổ theo chiều rộng.