คอมโพเนนต์การนำทางมีNavigationUI
คลาสนี้มีเมธอดแบบคงที่ที่จัดการการนำทางด้วย
แถบแอป ลิ้นชักการนำทาง และการนำทางด้านล่าง
แถบแอปด้านบน
แถบแอปด้านบน ให้ตำแหน่งที่สอดคล้องกันที่ด้านบนของแอปแสดงข้อมูล และการทำงานจากหน้าจอปัจจุบัน
![หน้าจอแสดงแถบแอปด้านบน](https://developer.android.com/static/topic/libraries/architecture/images/top-app-bar.png?authuser=8&hl=th)
NavigationUI
มีวิธีอัปเดตเนื้อหาในตำแหน่งบนสุดโดยอัตโนมัติ
แถบแอปขณะที่ผู้ใช้ไปยังส่วนต่างๆ ของแอป ตัวอย่างเช่น NavigationUI
ใช้เมธอด
ป้ายกำกับปลายทางจากกราฟการนำทางเพื่อเก็บชื่อแอปยอดนิยมไว้
อัปเดตเป็นเวอร์ชันล่าสุดแล้ว
<navigation> <fragment ... android:label="Page title"> ... </fragment> </navigation>
เมื่อใช้ NavigationUI
กับการใช้งานแถบแอปยอดนิยมที่กล่าวถึงด้านล่าง
ป้ายกำกับที่คุณแนบกับปลายทางอาจถูกสร้างโดยอัตโนมัติจาก
อาร์กิวเมนต์ที่ระบุไปยังปลายทางโดยใช้รูปแบบ {argName}
ใน
ป้ายกำกับ
NavigationUI
รองรับแถบแอปยอดนิยมประเภทต่อไปนี้
ดูข้อมูลเพิ่มเติมเกี่ยวกับแถบแอปได้ที่ตั้งค่าแถบแอป
การกำหนดค่าแถบแอป
NavigationUI
ใช้ AppBarConfiguration
เพื่อจัดการลักษณะการทำงานของปุ่มการนำทางที่มุมบนซ้าย
ของพื้นที่แสดงผลของแอป ลักษณะการทำงานของปุ่มการนำทางจะเปลี่ยนไปตาม
ว่าผู้ใช้อยู่ในปลายทางระดับบนสุดหรือไม่
ปลายทางระดับบนสุดคือรูทหรือปลายทางระดับสูงสุดในชุด ปลายทางที่สัมพันธ์กันตามลำดับชั้น ปลายทางระดับบนสุดไม่แสดง ปุ่มขึ้นในแถบแอปด้านบนเนื่องจากไม่มีปลายทางระดับที่สูงกว่า โดย โดยค่าเริ่มต้น ปลายทางเริ่มต้นของแอปจะเป็นปลายทางระดับบนสุดเพียงแห่งเดียว
เมื่อผู้ใช้อยู่ที่ปลายทางระดับบนสุด ปุ่มการนำทางจะกลายเป็น
ไอคอนลิ้นชัก
หากปลายทางใช้
DrawerLayout
หากปลายทางไม่ได้ใช้
DrawerLayout
ปุ่มการนําทางซ่อนอยู่ เมื่อผู้ใช้อยู่ที่ปลายทางอื่น ปุ่มการนำทางจะปรากฏเป็นปุ่มขึ้น
หากต้องการกำหนดค่าปุ่มการนำทางโดยใช้เฉพาะปลายทางเริ่มต้นเป็น
ปลายทางระดับบนสุด สร้างออบเจ็กต์
AppBarConfiguration
แล้วส่งผ่านในกราฟการนำทางที่เกี่ยวข้องดังที่แสดงด้านล่าง
Kotlin
val appBarConfiguration = AppBarConfiguration(navController.graph)
Java
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
ในบางกรณี คุณอาจต้องกำหนดปลายทางระดับบนสุดหลายแห่งแทน
ของการใช้ปลายทางเริ่มต้นเริ่มต้น การใช้ BottomNavigationView
เป็น
กรณีการใช้งานทั่วไปสำหรับกรณีนี้ ซึ่งคุณอาจมีหน้าจอข้างเคียงที่ไม่ได้
ซึ่งมีลำดับชั้นที่เกี่ยวข้องซึ่งกันและกัน และแต่ละลำดับชั้นอาจมีชุดที่เกี่ยวข้อง
ปลายทาง ในกรณีเช่นนี้ คุณสามารถส่งชุดปลายทางแทนได้
รหัสไปยังเครื่องมือสร้างดังที่แสดงด้านล่าง
Kotlin
val appBarConfiguration = AppBarConfiguration(setOf(R.id.main, R.id.profile))
Java
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(R.id.main, R.id.profile).build();
สร้างแถบเครื่องมือ
หากต้องการสร้างแถบเครื่องมือด้วย NavigationUI
ขั้นแรกให้กำหนดแถบใน
กิจกรรมที่แสดงดังนี้
<LinearLayout> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" /> <androidx.fragment.app.FragmentContainerView android:id="@+id/nav_host_fragment" ... /> ... </LinearLayout>
ถัดไป โทรหา setupWithNavController()
จากเมธอด onCreate()
ของกิจกรรมหลัก ดังที่แสดงใน
ตัวอย่าง:
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); }
เพื่อกำหนดค่าปุ่มการนำทางให้แสดงเป็นปุ่มขึ้นสำหรับทุกคน
ปลายทาง ให้ส่งผ่านชุดรหัสปลายทางที่ว่างเปล่าสำหรับระดับบนสุด
ปลายทางเมื่อสร้างAppBarConfiguration
สิ่งนี้อาจมีประโยชน์
ตัวอย่างเช่น หากคุณมีกิจกรรมที่ 2 ที่ควรแสดงปุ่ม "ขึ้น"
ใน Toolbar
ในจุดหมายทั้งหมด เพื่อช่วยให้ผู้ใช้ย้อนกลับ
กับกิจกรรมของผู้ปกครอง เมื่อไม่มีจุดหมายอื่นๆ ที่ด้านหลัง
สแต็ก คุณสามารถใช้
setFallbackOnNavigateUpListener()
เพื่อควบคุมพฤติกรรมการสำรองในกรณีที่ navigateUp()
จะ
ไม่ดำเนินการใดๆ ดังที่แสดงในตัวอย่างต่อไปนี้
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); }
รวมการยุบแถบเครื่องมือเลย์เอาต์
หากต้องการรวม CollapsingToolbarLayout
ไว้ในแถบเครื่องมือของคุณ ก่อนอื่นให้กำหนด
แถบเครื่องมือและเลย์เอาต์โดยรอบในกิจกรรม
<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>
ถัดไป โทรหา setupWithNavController()
จากเมธอด onCreate
ของกิจกรรมหลักดังที่แสดงด้านล่าง
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); }
แถบการดำเนินการ
หากต้องการเพิ่มการสนับสนุนการนำทางลงในแถบการดำเนินการเริ่มต้น ให้โทร
setupActionBarWithNavController()
จากเมธอด onCreate()
ของกิจกรรมหลักดังที่แสดงด้านล่าง โปรดทราบว่า
ต้องประกาศ AppBarConfiguration
ของคุณนอก onCreate()
เนื่องจากคุณ
และใช้เมื่อลบล้าง 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); }
ถัดไป ให้ลบล้าง onSupportNavigateUp()
เพื่อจัดการการนำทางขึ้น
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(); }
รองรับแถบแอปรูปแบบต่างๆ
การเพิ่มแถบแอปด้านบนลงในกิจกรรมจะทำงานได้ดีเมื่อเลย์เอาต์ของแถบแอป สำหรับแต่ละปลายทางในแอปของคุณเหมือนกัน อย่างไรก็ตาม หากแถบแอปด้านบนมีการเปลี่ยนแปลง ในปลายทางต่างๆ อย่างมาก จากนั้นพิจารณานำแถบแอปด้านบนออกจาก กิจกรรมของคุณแล้วนำไปกำหนดในส่วนปลายทางแต่ละส่วนแทน
ตัวอย่างเช่น หนึ่งในปลายทางของคุณอาจใช้ Toolbar
มาตรฐาน
อีกแอปหนึ่งใช้ AppBarLayout
เพื่อสร้างแถบแอปที่ซับซ้อนขึ้นด้วยแท็บ เช่น
รูปที่ 2
![รูปแบบแถบแอปยอดนิยม 2 อันดับแรก แถบเครื่องมือมาตรฐานทางด้านซ้าย
Appbarlayout ที่มีแถบเครื่องมือและแท็บอยู่ด้านขวา](https://developer.android.com/static/images/guide/navigation/app-bar-variations.png?authuser=8&hl=th)
Toolbar
ทางด้านขวา AppBarLayout
ที่มี
Toolbar
และแท็บหากต้องการใช้ตัวอย่างนี้ภายในส่วนย่อยปลายทางของคุณโดยใช้
NavigationUI
ให้กำหนดแถบแอปในเลย์เอาต์ Fragment แต่ละรายการก่อน
เริ่มต้นด้วยส่วนย่อยปลายทางที่ใช้แถบเครื่องมือมาตรฐาน
<LinearLayout>
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
... />
...
</LinearLayout>
ถัดไป ให้กำหนดส่วนย่อยปลายทางที่ใช้แถบแอปกับแท็บดังนี้
<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>
ตรรกะการกำหนดค่าการนำทางจะเหมือนกันสำหรับ Fragment ทั้งสองนี้
เว้นแต่ว่าคุณควรโทรหา
setupWithNavController()
จากภายในเมธอด onViewCreated()
ของแต่ละส่วนย่อย แทนที่จะเริ่มต้น
จากกิจกรรม ได้แก่
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); }
เชื่อมโยงจุดหมายเข้ากับรายการในเมนู
NavigationUI
ยังมีตัวช่วยสำหรับการเชื่อมโยงปลายทางกับ UI ที่ขับเคลื่อนด้วยเมนู
คอมโพเนนต์ NavigationUI
มีเมธอด Helper
onNavDestinationSelected()
,
ซึ่งจะใช้ MenuItem
พร้อมด้วย
NavController
ที่โฮสต์
ปลายทางที่เกี่ยวข้อง หาก id
ของ MenuItem
ตรงกับ id
ของ
ปลายทาง NavController
จะสามารถนำทางไปยังปลายทางนั้น
ตัวอย่างเช่น ข้อมูลโค้ด XML ด้านล่างกำหนดรายการในเมนูและปลายทางที่มี
id
, 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>
ตัวอย่างเช่น หากคุณเพิ่มเมนูผ่านonCreateOptionsMenu()
ของกิจกรรม
คุณสามารถเชื่อมโยงรายการเมนูกับปลายทางได้โดยการลบล้างการตั้งค่า
onOptionsItemSelected()
เพื่อโทรหา onNavDestinationSelected()
ตามที่แสดงใน
ตัวอย่างต่อไปนี้
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); }
ตอนนี้เมื่อผู้ใช้คลิกรายการในเมนู details_page_fragment
แอป
นำทางไปยังปลายทางที่เกี่ยวข้องด้วย id
เดียวกันโดยอัตโนมัติ
เพิ่มลิ้นชักการนำทาง
ลิ้นชักการนำทางคือแผง UI ที่แสดงเมนูการนำทางหลักของแอป
ลิ้นชักจะปรากฏขึ้นเมื่อผู้ใช้แตะไอคอนลิ้นชัก
ในแถบแอป หรือเมื่อผู้ใช้ปัดนิ้วจากขอบด้านซ้ายของแอป
บนหน้าจอ
![ลิ้นชักที่เปิดอยู่ที่แสดงเมนูการนำทาง](https://developer.android.com/static/images/topic/libraries/architecture/navigation-drawer.png?authuser=8&hl=th)
ไอคอนลิ้นชักปรากฏอยู่บน
ปลายทางระดับบนสุดที่ใช้ DrawerLayout
หากต้องการเพิ่มลิ้นชักการนำทาง ให้ประกาศ
DrawerLayout
เป็นรูท
ภายใน DrawerLayout
ให้เพิ่มเลย์เอาต์สำหรับเนื้อหา UI หลัก และ
อีกมุมมองหนึ่งที่มีเนื้อหาของลิ้นชักการนำทาง
ตัวอย่างเช่น เลย์เอาต์ต่อไปนี้ใช้ DrawerLayout
ที่มีมุมมองย่อย 2 มุมมอง ได้แก่
NavHostFragment
ถึง
มีเนื้อหาหลักและ
NavigationView
เพื่อดูเนื้อหาของลิ้นชักการนำทาง
<?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>
ถัดไป ให้เชื่อมต่อ DrawerLayout
ลงในกราฟการนำทาง โดยส่งต่อไปยัง AppBarConfiguration
ดังที่แสดงใน
ตัวอย่างต่อไปนี้
Kotlin
val appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)
Java
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()) .setDrawerLayout(drawerLayout) .build();
ถัดไป ในชั้นเรียนกิจกรรมหลัก ให้โทรหา
setupWithNavController()
จากเมธอด onCreate()
ของกิจกรรมหลักดังที่แสดงด้านล่าง
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); }
จะเริ่มต้นใน
การนำทาง 2.4.0-alpha01
สถานะของแต่ละรายการในเมนูจะได้รับการบันทึกและคืนค่าเมื่อคุณใช้
setupWithNavController
การไปยังส่วนต่างๆ ด้านล่าง
NavigationUI
ยังจัดการการนำทางด้านล่างได้ด้วย เมื่อผู้ใช้เลือกเมนู
รายการ NavController
รายการ
onNavDestinationSelected()
แล้วอัปเดตรายการที่เลือก
ในแถบนำทางด้านล่างโดยอัตโนมัติ
![แถบนำทางด้านล่าง](https://developer.android.com/static/topic/libraries/architecture/images/bottom-navigation.png?authuser=8&hl=th)
หากต้องการสร้างแถบนำทางด้านล่างในแอป ให้กําหนดแถบในส่วนหลักก่อน ตามที่แสดงด้านล่าง
<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>
ถัดไป ในชั้นเรียนกิจกรรมหลัก ให้โทรหา
setupWithNavController()
จากเมธอด onCreate()
ของกิจกรรมหลักดังที่แสดงด้านล่าง
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); }
จะเริ่มต้นใน
การนำทาง 2.4.0-alpha01
สถานะของแต่ละรายการในเมนูจะได้รับการบันทึกและคืนค่าเมื่อคุณใช้
setupWithNavController
สำหรับตัวอย่างที่ครอบคลุมที่มีการนำทางด้านล่าง โปรดดู ตัวอย่างการนำทางขั้นสูงของคอมโพเนนต์สถาปัตยกรรม Android ใน GitHub
ฟังเหตุการณ์การนำทาง
โต้ตอบกับ NavController
เป็นวิธีหลักในการนำทางไปยังปลายทางต่างๆ NavController
มีหน้าที่แทนที่เนื้อหาของ NavHost
โดยระบุปลายทางใหม่ ในหลายกรณี องค์ประกอบ UI เช่น แถบแอปด้านบน หรือ
การควบคุมการนำทางแบบถาวรอื่นๆ เช่น BottomNavigationBar
แบบสดกลางแจ้ง
ของ NavHost
และจะต้องได้รับการอัปเดตขณะไปยังปลายทางต่างๆ
NavController
มีอินเทอร์เฟซ OnDestinationChangedListener
ที่
เรียกใช้เมื่อปลายทางปัจจุบันของ NavController
หรืออาร์กิวเมนต์มีการเปลี่ยนแปลง ผู้ฟังใหม่สามารถลงทะเบียนผ่าน
addOnDestinationChangedListener()
โปรดทราบว่าเมื่อโทรหา addOnDestinationChangedListener()
หาก
มีปลายทางปัจจุบันอยู่ จะมีการส่งไปยัง Listener ของคุณทันที
NavigationUI
ใช้ OnDestinationChangedListener
เพื่อสร้าง UI ทั่วไปเหล่านี้
พิจารณาการนำทางของคอมโพเนนต์ แต่โปรดทราบว่าคุณสามารถใช้
OnDestinationChangedListener
เพื่อสร้าง UI หรือธุรกิจที่กำหนดเอง
รับรู้ถึงเหตุการณ์การนำทางได้
ตัวอย่างเช่น คุณอาจมีองค์ประกอบ UI ทั่วไปที่คุณตั้งใจจะแสดง
พื้นที่บางส่วนของแอป
ขณะซ่อนส่วนอื่นๆ ใช้ของคุณเอง
OnDestinationChangedListener
คุณสามารถเลือกแสดงหรือซ่อน UI เหล่านี้ได้
ตามปลายทางเป้าหมาย ดังที่แสดงในตัวอย่างต่อไปนี้
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); } } });
Listener ที่ใช้อาร์กิวเมนต์
อีกวิธีหนึ่งคือ คุณสามารถใช้อาร์กิวเมนต์ที่มีค่าเริ่มต้นอยู่ภายใน
กราฟการนำทาง ซึ่งสามารถใช้โดยตัวควบคุม UI ที่เหมาะสม
เพื่ออัปเดตสถานะ เช่น แทนที่จะสร้างพื้นฐานตามตรรกะในมิติข้อมูล
OnDestinationChangedListener
ในรหัสปลายทางตามก่อนหน้า
เช่น เราสร้างอาร์กิวเมนต์ใน 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>
ระบบจะไม่ใช้อาร์กิวเมนต์นี้เมื่อ
การนำทางไปยังจุดหมาย แต่
เป็นวิธีแนบข้อมูลเพิ่มเติมไปยังปลายทางได้โดยใช้
defaultValue
ในกรณีนี้ ค่าจะเป็นตัวระบุว่าแถบแอป
ควรจะแสดงเมื่ออยู่ที่ปลายทางนี้
ตอนนี้เราสามารถเพิ่ม OnDestinationChangedListener
ใน 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
เรียกใช้ Callback นี้เมื่อปลายทางของการนำทางเปลี่ยนแปลง
Activity
อัปเดตสถานะหรือการมองเห็นคอมโพเนนต์ UI ได้แล้ว
ที่เป็นเจ้าของตามอาร์กิวเมนต์ที่ได้รับใน Callback
ข้อดีอย่างหนึ่งของวิธีนี้คือ Activity
เห็นเฉพาะ
อาร์กิวเมนต์ในกราฟการนำทางและไม่รู้จัก Fragment
แต่ละรายการ
บทบาทและความรับผิดชอบ ในทำนองเดียวกัน ส่วนย่อยแต่ละรายการไม่ทราบ
เกี่ยวกับ Activity
ที่มีและคอมโพเนนต์ UI ที่ URL ดังกล่าวเป็นเจ้าของ
แหล่งข้อมูลเพิ่มเติม
หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับการนำทาง โปรดดูแหล่งข้อมูลเพิ่มเติมต่อไปนี้
ตัวอย่าง
- ตัวอย่างการไปยังส่วนต่างๆ ของคอมโพเนนต์สถาปัตยกรรม Android เบื้องต้น
- ตัวอย่างการนำทางขั้นสูงของคอมโพเนนต์สถาปัตยกรรม Android
Codelab
บล็อกโพสต์
วิดีโอ
- แนวทางปฏิบัติแนะนำ 10 ข้อสำหรับการย้ายไปยังกิจกรรมเดียว
- กิจกรรมเดียว: ทำไม เวลา และอย่างไร (Android Dev Summit ปี 2018)
- Android Jetpack: จัดการการนำทางใน UI ด้วยตัวควบคุมการนำทาง (Google I/O '18)