Thành phần Điều hướng bao gồm một lớp NavigationUI
. Lớp này chứa các phương thức tĩnh giúp quản lý cách điều hướng bằng thanh ứng dụng ở trên cùng, ngăn điều hướng và trình đơn điều hướng ở dưới cùng.
Thanh ứng dụng trên cùng
Thanh ứng dụng trên cùng (top app bar) cung cấp một vị trí nhất quán theo đầu ứng dụng để hiển thị thông tin và các hành động trên màn hình hiện tại.
![màn hình cho thấy một thanh ứng dụng trên cùng](https://developer.android.google.cn/static/topic/libraries/architecture/images/top-app-bar.png?authuser=19&hl=vi)
NavigationUI
chứa các phương thức tự động cập nhật nội dung trên thanh ứng dụng ở trên cùng khi người dùng di chuyển qua ứng dụng. Ví dụ: NavigationUI
sử dụng nhãn đích đến trên biểu đồ điều hướng để luôn cập nhật tiêu đề của thanh ứng dụng ở trên cùng.
<navigation> <fragment ... android:label="Page title"> ... </fragment> </navigation>
Khi sử dụng NavigationUI
cùng với cách triển khai thanh ứng dụng ở trên cùng như thảo luận dưới đây, nhãn bạn đính kèm với đích đến có thể tự động được điền bằng các đối số cung cấp cho đích đến đó thông qua định dạng của {argName}
trong nhãn.
NavigationUI
hỗ trợ các loại thanh ứng dụng trên cùng sau đây:
Để biết thêm thông tin về thanh ứng dụng, hãy xem nội dung Thiết lập thanh ứng dụng.
AppBarConfiguration
NavigationUI
sử dụng đối tượng AppBarConfiguration
để quản lý hoạt động của nút Điều hướng ở góc trên bên trái khu vực hiển thị của ứng dụng. Hành vi của nút Điều hướng thay đổi tuỳ thuộc vào việc người dùng có đang ở đích cấp cao nhất hay không.
Đích đến (destination) cấp cao nhất là đích gốc hoặc cấp cao nhất trong một tập hợp các đích đến liên quan theo hệ phân cấp. Đích cấp cao nhất không hiển thị nút Mũi tên lên trong thanh ứng dụng trên cùng vì không có đích cấp cao hơn. Theo mặc định, đích đến bắt đầu của ứng dụng là đích đến cấp cao nhất duy nhất.
Khi người dùng ở một đích đến cấp cao nhất, nút Navigation (Điều hướng) sẽ trở thành biểu tượng ngăn nếu đích đến đó sử dụng
DrawerLayout
. Nếu đích không sử dụng DrawerLayout
, nút Điều hướng sẽ bị ẩn. Khi người dùng đang ở đích khác, nút Điều hướng sẽ xuất hiện dưới dạng nút Mũi tên lên .
Để định cấu hình nút Navigation (Điều hướng) chỉ sử dụng đích đến bắt đầu làm đích đến cấp cao nhất, hãy tạo một đối tượng
AppBarConfiguration
rồi truyền vào biểu đồ điều hướng tương ứng, như minh hoạ dưới đây:
Kotlin
val appBarConfiguration = AppBarConfiguration(navController.graph)
Java
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
Trong một số trường hợp, bạn có thể phải xác định nhiều đích cấp cao nhất thay vì sử dụng đích xuất phát mặc định. Việc dùng BottomNavigationView
là một trường hợp sử dụng phổ biến cho trường hợp này, trong đó bạn có thể có các màn hình đồng cấp không liên quan theo hệ phân cấp và mỗi màn hình có thể có một tập hợp các đích đến liên quan riêng. Đối với các trường hợp như vậy, bạn có thể truyền một tập hợp mã nhận dạng đích đến vào hàm khởi tạo, như minh hoạ dưới đây:
Kotlin
val appBarConfiguration = AppBarConfiguration(setOf(R.id.main, R.id.profile))
Java
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(R.id.main, R.id.profile).build();
Tạo Thanh công cụ
Để Tạo thanh công cụ (Toolbar) bằng NavigationUI
, trước tiên, hãy xác định thanh đps trong hoạt động chính của bạn, như minh hoạ dưới đây:
<LinearLayout> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" /> <androidx.fragment.app.FragmentContainerView android:id="@+id/nav_host_fragment" ... /> ... </LinearLayout>
Tiếp theo, hãy gọi setupWithNavController()
qua phương thức onCreate()
của hoạt động chính, như minh hoạ trong ví dụ dưới đây:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { setContentView(R.layout.activity_main) ... val navController = findNavController(R.id.nav_host_fragment) val appBarConfiguration = AppBarConfiguration(navController.graph) findViewById<Toolbar>(R.id.toolbar) .setupWithNavController(navController, appBarConfiguration) }
Java
@Override protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); ... NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build(); Toolbar toolbar = findViewById(R.id.toolbar); NavigationUI.setupWithNavController( toolbar, navController, appBarConfiguration); }
Để định cấu hình sao cho nút Navigation (Điều hướng) xuất hiện dưới dạng nút Up (Mũi tên lên) cho mọi đích đến, hãy truyền một tập hợp mã nhận dạng đích đến trống vào các đích đến cấp cao nhất khi tạo AppBarConfiguration
. Ví dụ: điều này có thể hữu ích trong trường hợp bạn có hoạt động thứ hai và cần hiển thị nút Up (Mũi tên lên) trong Toolbar
trên mọi đích đến. Điều này cho phép người dùng quay lại hoạt động mẹ khi không có đích nào khác trên ngăn xếp lui Bạn có thể sử dụng setFallbackOnNavigateUpListener()
để kiểm soát hành vi dự phòng cho trường hợp navigateUp()
không làm gì khác, như thể hiện trong ví dụ sau:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { ... val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment val navController = navHostFragment.navController val appBarConfiguration = AppBarConfiguration( topLevelDestinationIds = setOf(), fallbackOnNavigateUpListener = ::onSupportNavigateUp ) findViewById<Toolbar>(R.id.toolbar) .setupWithNavController(navController, appBarConfiguration) }
Java
@Override protected void onCreate(Bundle savedInstanceState) { ... NavHostFragment navHostFragment = (NavHostFragment) supportFragmentManager.findFragmentById(R.id.nav_host_fragment); NavController navController = navHostFragment.getNavController(); AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder() .setFallbackOnNavigateUpListener(::onSupportNavigateUp) .build(); Toolbar toolbar = findViewById(R.id.toolbar); NavigationUI.setupWithNavController( toolbar, navController, appBarConfiguration); }
Bao gồm CollapsingToolbarLayout
Để đưa CollapsingToolbarLayout
vào Thanh công cụ, trước tiên, hãy xác định Thanh công cụ và bố cục xung quanh trong hoạt động của bạn, như thể hiện dưới đây:
<LinearLayout> <com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent" android:layout_height="@dimen/tall_toolbar_height"> <com.google.android.material.appbar.CollapsingToolbarLayout android:id="@+id/collapsing_toolbar_layout" android:layout_width="match_parent" android:layout_height="match_parent" app:contentScrim="?attr/colorPrimary" app:expandedTitleGravity="top" app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_collapseMode="pin"/> </com.google.android.material.appbar.CollapsingToolbarLayout> </com.google.android.material.appbar.AppBarLayout> <androidx.fragment.app.FragmentContainerView android:id="@+id/nav_host_fragment" ... /> ... </LinearLayout>
Tiếp theo, hãy gọi setupWithNavController()
qua phương thức onCreate
của hoạt động chính như thể hiện dưới đây:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { setContentView(R.layout.activity_main) ... val layout = findViewById<CollapsingToolbarLayout>(R.id.collapsing_toolbar_layout) val toolbar = findViewById<Toolbar>(R.id.toolbar) val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment val navController = navHostFragment.navController val appBarConfiguration = AppBarConfiguration(navController.graph) layout.setupWithNavController(toolbar, navController, appBarConfiguration) }
Java
@Override protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); ... CollapsingToolbarLayout layout = findViewById(R.id.collapsing_toolbar_layout); Toolbar toolbar = findViewById(R.id.toolbar); NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment); NavController navController = navHostFragment.getNavController(); AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build(); NavigationUI.setupWithNavController(layout, toolbar, navController, appBarConfiguration); }
Thanh thao tác
Để hỗ trợ chức năng di chuyển cho thanh thao tác (action bar) mặc định, hãy gọi setupActionBarWithNavController()
qua phương thức onCreate()
của hoạt động chính như thể hiện dưới đây: Xin lưu ý rằng bạn cần khai báo AppBarConfiguration
bên ngoài onCreate()
vì bạn cũng sử dụng chế độ này khi ghi đè onSupportNavigateUp()
:
Kotlin
private lateinit var appBarConfiguration: AppBarConfiguration ... override fun onCreate(savedInstanceState: Bundle?) { ... val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment val navController = navHostFragment.navController appBarConfiguration = AppBarConfiguration(navController.graph) setupActionBarWithNavController(navController, appBarConfiguration) }
Java
AppBarConfiguration appBarConfiguration; ... @Override protected void onCreate(Bundle savedInstanceState) { ... NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment); NavController navController = navHostFragment.getNavController(); appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build(); NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration); }
Tiếp theo, hãy ghi đè onSupportNavigateUp()
để xử lý xử lý di chuyển Lên:
Kotlin
override fun onSupportNavigateUp(): Boolean { val navController = findNavController(R.id.nav_host_fragment) return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp() }
Java
@Override public boolean onSupportNavigateUp() { NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); return NavigationUI.navigateUp(navController, appBarConfiguration) || super.onSupportNavigateUp(); }
Hỗ trợ các biến thể của thanh ứng dụng
Bạn nên thêm thanh ứng dụng ở trên cùng vào hoạt động khi bố cục của thanh ứng dụng cho mỗi đích đến trong ứng dụng là giống nhau. Tuy nhiên, nếu thanh ứng dụng ở trên cùng có sự thay đổi đáng kể giữa các đích đến, hãy cân nhắc việc xoá thanh ứng dụng ở trên cùng khỏi hoạt động rồi khai báo thanh đó trong từng mảnh đích đến.
Ví dụ: một trong các đích đến có thể sử dụng Toolbar
tiêu chuẩn, trong khi một đích đến khác sử dụng AppBarLayout
để tạo thanh ứng dụng phức tạp hơn với các thẻ, như minh hoạ trong hình 2.
![two top app bar variations; a standard toolbar on the left, and an appbarlayout with a toolbar and tabs on the right (2 biến thể thanh ứng dụng ở trên cùng; 1 thanh công cụ chuẩn ở bên trái và 1 appbarlayout với thanh công cụ và các thẻ ở bên phải)](https://developer.android.google.cn/static/images/guide/navigation/app-bar-variations.png?authuser=19&hl=vi)
Toolbar
tiêu chuẩn. Ở bên phải, AppBarLayout
chứa Toolbar
và các thẻ.Để triển khai ví dụ này trong các mảnh đích đến bằng cách sử dụng NavigationUI
, trước tiên, hãy khai báo thanh ứng dụng trong mỗi bố cục mảnh, bắt đầu từ mảnh đích đến sử dụng thanh công cụ chuẩn:
<LinearLayout>
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
... />
...
</LinearLayout>
Tiếp theo, hãy xác định mảnh đích sử dụng thanh ứng dụng có các thẻ:
<LinearLayout>
<com.google.android.material.appbar.AppBarLayout
... />
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
... />
<com.google.android.material.tabs.TabLayout
... />
</com.google.android.material.appbar.AppBarLayout>
...
</LinearLayout>
Logic của cấu hình điều hướng là như nhau đối với cả hai mảnh này, ngoại trừ việc bạn nên gọi setupWithNavController()
ngay từ phương thức onViewCreated()
của từng mảnh, thay vì khởi chạy các mảnh trong hoạt động:
Kotlin
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val navController = findNavController() val appBarConfiguration = AppBarConfiguration(navController.graph) view.findViewById<Toolbar>(R.id.toolbar) .setupWithNavController(navController, appBarConfiguration) }
Java
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { NavController navController = Navigation.findNavController(view); AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build(); Toolbar toolbar = view.findViewById(R.id.toolbar); NavigationUI.setupWithNavController( toolbar, navController, appBarConfiguration); }
Gắn đích với mục trong trình đơn
NavigationUI
cũng cung cấp các trình trợ giúp để liên kết các đích với thành phần giao diện người dùng theo trình đơn. NavigationUI
chứa một phương thức trợ giúp onNavDestinationSelected()
, sử dụng MenuItem
cùng với NavController
lưu trữ đích đến liên kết. Nếu id
của MenuItem
khớp với id
của đích, thì NavController
có thể điều hướng đến đích đó.
Ví dụ: các đoạn mã XML dưới đây xác định một mục trong trình đơn và một đích đến có id
phổ biến là details_page_fragment
:
<?xml version="1.0" encoding="utf-8"?> <navigation xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android" ... > ... <fragment android:id="@+id/details_page_fragment" android:label="@string/details" android:name="com.example.android.myapp.DetailsFragment" /> </navigation>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> ... <item android:id="@+id/details_page_fragment" android:icon="@drawable/ic_details" android:title="@string/details" /> </menu>
Ví dụ: Nếu bạn thêm trình đơn qua onCreateOptionsMenu()
của Hoạt động, bạn có thể liên kết các mục trong trình đơn với đích đến bằng cách ghi đè onOptionsItemSelected()
của Hoạt động để gọi onNavDestinationSelected()
, như minh hoạ trong ví dụ dưới đây:
Kotlin
override fun onOptionsItemSelected(item: MenuItem): Boolean { val navController = findNavController(R.id.nav_host_fragment) return item.onNavDestinationSelected(navController) || super.onOptionsItemSelected(item) }
Java
@Override public boolean onOptionsItemSelected(MenuItem item) { NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); return NavigationUI.onNavDestinationSelected(item, navController) || super.onOptionsItemSelected(item); }
Bây giờ, khi người dùng nhấp vào mục trong trình đơn details_page_fragment
, ứng dụng
sẽ tự động chuyển đến đích tương ứng bằng cùng một id
.
Thêm ngăn điều hướng
Ngăn điều hướng (navigation drawer) là một bảng điều khiển trên giao diện người dùng cho thấy trình đơn điều hướng chính của ứng dụng.
Ngăn này sẽ xuất hiện khi người dùng nhấn vào biểu tượng ngăn trong thanh ứng dụng hoặc khi người dùng vuốt từ mép trái màn hình.
![một ngăn mở cho thấy trình đơn điều hướng](https://developer.android.google.cn/static/images/topic/libraries/architecture/navigation-drawer.png?authuser=19&hl=vi)
Biểu tượng ngăn kéo xuất hiện trên tất cả đích cấp cao nhất sử dụng DrawerLayout
.
Để thêm một ngăn điều hướng, trước tiên, hãy khai báo DrawerLayout
làm thành phần hiển thị gốc. Bên trong DrawerLayout
, hãy thêm một bố cục cho nội dung chính trên giao diện người dùng và một thành phần hiển thị khác chứa nội dung của ngăn điều hướng.
Ví dụ: bố cục sau sử dụng DrawerLayout
với hai thành phần hiển thị con: một
NavHostFragment
để chứa nội dung chính và một NavigationView
cho nội dung của ngăn điều hướng.
<?xml version="1.0" encoding="utf-8"?>
<!-- Use DrawerLayout as root container for activity -->
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<!-- Layout to contain contents of main body of screen (drawer will slide over this) -->
<androidx.fragment.app.FragmentContainerView
android:name="androidx.navigation.fragment.NavHostFragment"
android:id="@+id/nav_host_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
<!-- Container for contents of drawer - use NavigationView to make configuration easier -->
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true" />
</androidx.drawerlayout.widget.DrawerLayout>
Tiếp theo, hãy kết nối DrawerLayout
với biểu đồ điều hướng bằng cách truyền biểu đồ đó vào AppBarConfiguration
, như minh hoạ trong ví dụ dưới đây:
Kotlin
val appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)
Java
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()) .setDrawerLayout(drawerLayout) .build();
Tiếp theo, trong lớp hoạt động chính, hãy gọi setupWithNavController()
qua phương thức onCreate()
của hoạt động chính như thể hiện dưới đây:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { setContentView(R.layout.activity_main) ... val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment val navController = navHostFragment.navController findViewById<NavigationView>(R.id.nav_view) .setupWithNavController(navController) }
Java
@Override protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); ... NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment); NavController navController = navHostFragment.getNavController(); NavigationView navView = findViewById(R.id.nav_view); NavigationUI.setupWithNavController(navView, navController); }
Kể từ Navigation 2.4.0-alpha01, trạng thái của từng mục trong trình đơn sẽ được lưu và khôi phục khi bạn sử dụng setupWithNavController
.
Thanh điều hướng dưới cùng
NavigationUI
cũng có thể xử lý thao tác ở dưới cùng. Khi người dùng chọn một mục trong trình đơn, NavController
sẽ gọi onNavDestinationSelected()
và tự động cập nhật mục đã chọn trong thanh điều hướng dưới cùng (bottom navigation bar).
![thanh điều hướng ở dưới cùng](https://developer.android.google.cn/static/topic/libraries/architecture/images/bottom-navigation.png?authuser=19&hl=vi)
Để tạo thanh điều hướng dưới cùng trong ứng dụng, trước tiên, hãy xác định thanh đó trong hoạt động chính của bạn, như thể hiện dưới đây.
<LinearLayout> ... <androidx.fragment.app.FragmentContainerView android:id="@+id/nav_host_fragment" ... /> <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bottom_nav" app:menu="@menu/menu_bottom_nav" /> </LinearLayout>
Tiếp theo, trong lớp hoạt động chính, hãy gọi setupWithNavController()
qua phương thức onCreate()
của hoạt động chính như thể hiện dưới đây:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { setContentView(R.layout.activity_main) ... val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment val navController = navHostFragment.navController findViewById<BottomNavigationView>(R.id.bottom_nav) .setupWithNavController(navController) }
Java
@Override protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); ... NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment); NavController navController = navHostFragment.getNavController(); BottomNavigationView bottomNav = findViewById(R.id.bottom_nav); NavigationUI.setupWithNavController(bottomNav, navController); }
Kể từ Navigation 2.4.0-alpha01, trạng thái của từng mục trong trình đơn sẽ được lưu và khôi phục khi bạn sử dụng setupWithNavController
.
Để biết ví dụ toàn diện về cách cung cấp thanh điều hướng ở dưới cùng, hãy xem, nội dung Mẫu điều hướng nâng cao cho bộ thành phần cấu trúc Android trên GitHub.
Nghe sự kiện điều hướng
Tương tác với NavController
là phương thức chính để di chuyển giữa các đích. NavController
có trách nhiệm thay thế nội dung của NavHost
bằng đích đến mới. Trong nhiều trường hợp, các thành phần trên giao diện người dùng (chẳng hạn như thanh ứng dụng ở trên cùng hoặc các nút điều khiển thao tác cố định khác như BottomNavigationBar
) nằm bên ngoài NavHost
và cần được cập nhật khi bạn di chuyển giữa các đích đến.
NavController
cung cấp giao diện OnDestinationChangedListener
được gọi khi đích hiện tại của NavController
hoặc đối số của thành phần này thay đổi. Bạn có thể đăng ký trình nghe mới thông qua phương thức addOnDestinationChangedListener()
. Lưu ý rằng khi gọi addOnDestinationChangedListener()
, nếu đích hiện tại đang tồn tại, đích đó sẽ được gửi ngay đến trình nghe
NavigationUI
sử dụng OnDestinationChangedListener
để làm cho các thành phần giao diện người dùng phổ biến này nhận biết được thành phần điều hướng. Tuy nhiên, hãy lưu ý rằng bạn cũng có thể sử dụng riêng OnDestinationChangedListener
để giúp thành phần giao diện người dùng tuỳ chỉnh hoặc logic doanh nghiệp nhận biết được sự kiện điều hướng.
Ví dụ: có thể bạn có các thành phần giao diện người dùng phổ biến mà bạn dự định hiển thị trong một số khu vực của ứng dụng trong khi ẩn các thành phần đó trong các khu vực khác. Khi sử dụng OnDestinationChangedListener
của riêng mình, bạn có thể hiện hoặc ẩn các thành phần giao diện người dùng này một cách có chọn lọc dựa trên đích, như trong ví dụ sau:
Kotlin
navController.addOnDestinationChangedListener { _, destination, _ -> if(destination.id == R.id.full_screen_destination) { toolbar.visibility = View.GONE bottomNavigationView.visibility = View.GONE } else { toolbar.visibility = View.VISIBLE bottomNavigationView.visibility = View.VISIBLE } }
Java
navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() { @Override public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) { if(destination.getId() == R.id.full_screen_destination) { toolbar.setVisibility(View.GONE); bottomNavigationView.setVisibility(View.GONE); } else { toolbar.setVisibility(View.VISIBLE); bottomNavigationView.setVisibility(View.VISIBLE); } } });
Trình nghe dựa trên đối số
Thay vào đó, bạn cũng có thể sử dụng các đối số có giá trị mặc định trong biểu đồ điều hướng. Trình điều khiển giao diện người dùng thích hợp có thể sử dụng biểu đồ này để cập nhật trạng thái. Ví dụ: thay vì dựa vào logic trong OnDestinationChangedListener
trên mã nhận dạng đích như trong ví dụ trước, chúng ta có thể tạo một đối số trong NavGraph
:
<?xml version="1.0" encoding="utf-8"?> <navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/navigation\_graph" app:startDestination="@id/fragmentOne"> <fragment android:id="@+id/fragmentOne" android:name="com.example.android.navigation.FragmentOne" android:label="FragmentOne"> <action android:id="@+id/action\_fragmentOne\_to\_fragmentTwo" app:destination="@id/fragmentTwo" /> </fragment> <fragment android:id="@+id/fragmentTwo" android:name="com.example.android.navigation.FragmentTwo" android:label="FragmentTwo"> <argument android:name="ShowAppBar" android:defaultValue="true" /> </fragment> </navigation>
Bạn không được dùng đối số này khi di chuyển tới đích đến mà thay vào đó là để đính kèm thông tin bổ sung vào đích đến bằng cách sử dụng defaultValue
. Trong trường hợp này, giá trị cho biết liệu thanh ứng dụng có nên hiện ra khi ở trên đích đến này hay không.
Bây giờ, chúng ta có thể thêm OnDestinationChangedListener
trong Activity
:
Kotlin
navController.addOnDestinationChangedListener { _, _, arguments -> appBar.isVisible = arguments?.getBoolean("ShowAppBar", false) == true }
Java
navController.addOnDestinationChangedListener( new NavController.OnDestinationChangedListener() { @Override public void onDestinationChanged( @NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments ) { boolean showAppBar = false; if (arguments != null) { showAppBar = arguments.getBoolean("ShowAppBar", false); } if(showAppBar) { appBar.setVisibility(View.VISIBLE); } else { appBar.setVisibility(View.GONE); } } } );
NavController
gọi lệnh gọi lại này bất cứ khi nào đích điều hướng thay đổi. Activity
nay có thể cập nhật trạng thái hoặc chế độ hiển thị của các thành phần giao diện người dùng mà ứng dụng sở hữu dựa trên các đối số nhận được trong lệnh gọi lại.
Một ưu điểm của phương pháp này là Activity
chỉ xem được các đối số trong biểu đồ điều hướng mà không biết từng vai trò và trách nhiệm Fragment
riêng lẻ. Tương tự, từng phần riêng lẻ không biết về Activity
chứa và các thành phần giao diện người dùng mà phần đó sở hữu.
Tài nguyên khác
Để tìm hiểu thêm về hoạt động điều hướng, hãy xem một số tài nguyên bổ sung sau đây.
Mẫu
- Mẫu điều hướng cơ bản trong bộ thành phần cấu trúc Android
- Mẫu điều hướng nâng cao trong bộ thành phần cấu trúc Android
Lớp học lập trình
- Navigation codelab (Lớp học lập trình về điều hướng)
Bài đăng trên blog
Video
- 10 phương pháp hay nhất để chuyển sang một hoạt động đơn
- Single Activity: Why, When, and How (Android Dev Summit '18) (Hoạt động đơn: Lý do, thời điểm và cách thức (Hội nghị Nhà phát triển Android '18))
- Android Jetpack: quản lý giao diện người dùng bằng Trình điều khiển điều hướng (Google I/O '18)