การนำทางแบบมีเงื่อนไขของ Android พร้อมการเข้าสู่ระบบ

Codelab นี้เป็นส่วนหนึ่งของหลักสูตร Android ขั้นสูงใน Kotlin คุณจะได้รับประโยชน์สูงสุดจากหลักสูตรนี้หากทำตาม Codelab ตามลำดับ แต่ไม่จำเป็นต้องทำ Codelab ของหลักสูตรทั้งหมดแสดงอยู่ในหน้า Landing Page ของ Codelab Android ขั้นสูงใน Kotlin


Codelab นี้สร้างขึ้นจาก Implementing Login on Android with FirebaseUI แม้ว่าคุณจะดาวน์โหลดโค้ดเริ่มต้นสำหรับโค้ดแล็บนี้ได้หากยังไม่ได้ทำโค้ดแล็บก่อนหน้า แต่คุณอาจพบว่าการทำโค้ดแล็บการติดตั้งใช้งานการเข้าสู่ระบบใน Android ด้วย FirebaseUI ให้เสร็จก่อนจะเป็นประโยชน์มากกว่า

บทนำ

หากแอปของคุณรองรับการเข้าสู่ระบบ กรณีการใช้งานที่พบบ่อยคือการสงวนบางส่วนของแอปไว้สำหรับผู้ใช้ที่เข้าสู่ระบบเท่านั้น เช่น คุณอาจต้องการสงวนหน้าจอการตั้งค่าของแอปไว้สำหรับผู้ใช้ที่เข้าสู่ระบบ

ในกรณีดังกล่าว คุณสามารถใช้การนำทางแบบมีเงื่อนไขเพื่อนำผู้ใช้ไปยังหน้าจอที่เหมาะสมตามสถานะการตรวจสอบสิทธิ์ของผู้ใช้

ในโค้ดแล็บนี้ คุณจะสร้างต่อยอดจากแอปที่มีอยู่เพื่อเพิ่มหน้าจอการตั้งค่าซึ่งผู้ใช้จะเข้าถึงได้ก็ต่อเมื่อเข้าสู่ระบบแล้วเท่านั้น คุณจะใช้คอมโพเนนต์การนำทางของ Android สำหรับงานนี้

สิ่งที่คุณควรทราบอยู่แล้ว

สิ่งที่คุณจะได้เรียนรู้

  • วิธีนำผู้ใช้ไปยังหน้าจอที่เหมาะสมของแอปโดยพิจารณาว่าผู้ใช้ได้เข้าสู่ระบบหรือไม่

สิ่งที่คุณต้องดำเนินการ

  • จัดการการนำทางผู้ใช้ไปยังหน้าจอที่ถูกต้องอย่างเหมาะสมหลังจากที่ผู้ใช้เข้าสู่ระบบสำเร็จ
  • ป้องกันไม่ให้ผู้ใช้เข้าถึงหน้าจอการตั้งค่าหากไม่ได้เข้าสู่ระบบ และเปลี่ยนเส้นทางผู้ใช้ไปยังหน้าจอเข้าสู่ระบบแทน

ใน Codelab ก่อนหน้านี้ คุณได้สร้างแอปที่แสดงข้อเท็จจริงเกี่ยวกับ Android นอกจากนี้ แอปของคุณยังอนุญาตให้ผู้ใช้เข้าสู่ระบบและออกจากระบบได้ด้วย สำหรับโค้ดแล็บนี้ คุณจะเพิ่มหน้าจอการตั้งค่าลงในแอปที่มีอยู่ ผู้ใช้จะเข้าถึงหน้าจอการตั้งค่าได้ก็ต่อเมื่อเข้าสู่ระบบแล้วเท่านั้น

หากผู้ใช้ไม่ได้เข้าสู่ระบบ เมื่อพยายามเข้าถึงหน้าจอการตั้งค่า แอปจะเปลี่ยนเส้นทางผู้ใช้ไปยังหน้าจอเข้าสู่ระบบ เมื่อขั้นตอนการเข้าสู่ระบบเสร็จสมบูรณ์แล้ว ระบบจะนำผู้ใช้กลับไปที่หน้าจอการตั้งค่าที่ผู้ใช้พยายามเข้าถึงในตอนแรก

Codelab นี้สร้างขึ้นจาก Implementing Login on Android with FirebaseUI แม้ว่าคุณจะดาวน์โหลดโค้ดเริ่มต้นสำหรับโค้ดแล็บนี้ได้หากยังไม่ได้ทำโค้ดแล็บก่อนหน้า แต่คุณอาจพบว่าการทำโค้ดแล็บการติดตั้งใช้งานการเข้าสู่ระบบใน Android ด้วย FirebaseUI ให้เสร็จก่อนจะเป็นประโยชน์มากกว่า

ดาวน์โหลดแอปตัวอย่าง โดยคุณทำได้ 2 วิธีดังนี้

ดาวน์โหลด Zip


... หรือโคลนที่เก็บ GitHub จากบรรทัดคำสั่งโดยใช้คำสั่งต่อไปนี้ แล้วเปลี่ยนไปที่สาขา start ของที่เก็บ

$  git clone https://github.com/googlecodelabs/android-kotlin-login-navigation

เมื่อโหลดโปรเจ็กต์ใน Android Studio แล้ว ให้ทำดังนี้

  1. เรียกใช้แอปในโปรแกรมจำลองหรืออุปกรณ์จริงเพื่อให้แน่ใจว่าได้ตั้งค่าสภาพแวดล้อมเรียบร้อยแล้วเพื่อเริ่มการพัฒนา

หากสำเร็จ คุณควรเห็นหน้าจอหลักที่แสดงข้อเท็จจริงสนุกๆ เกี่ยวกับ Android และปุ่มเข้าสู่ระบบที่มุมซ้ายบน


ฟีเจอร์ปัจจุบันของแอปเริ่มต้นมีดังนี้

  • หากผู้ใช้ไม่ได้เข้าสู่ระบบ การแตะปุ่มเข้าสู่ระบบจะเริ่มขั้นตอนการเข้าสู่ระบบและอนุญาตให้ผู้ใช้เข้าสู่ระบบด้วยอีเมลหรือบัญชี Google
  • หากผู้ใช้เข้าสู่ระบบแล้ว ปุ่มจะเปลี่ยนเป็นปุ่มออกจากระบบที่อนุญาตให้ผู้ใช้ออกจากระบบได้

ในงานนี้ คุณจะได้เพิ่มปุ่มในหน้าจอหลักที่ช่วยให้ผู้ใช้ไปยังหน้าจอการตั้งค่าได้ หน้าจอการตั้งค่าจะช่วยให้ผู้ใช้เลือกข้อเท็จจริงสนุกๆ ที่ต้องการให้แสดงในหน้าจอหลักได้ จากหน้าจอการตั้งค่า ผู้ใช้สามารถเลือกดูข้อเท็จจริงเกี่ยวกับ Android หรือข้อเท็จจริงเกี่ยวกับรัฐแคลิฟอร์เนีย

  1. เปิด fragment_main.xml
  2. ใน fragment_main.xml, ให้เพิ่มปุ่มการตั้งค่าที่ซ้อนอยู่ใน ConstraintLayout และวางไว้ที่มุมขวาบนของหน้าจอ

fragment_main.xml

<TextView
       android:id="@+id/settings_btn"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_margin="@dimen/text_margin"
       android:background="@color/colorAccent"
       android:padding="10dp"
       android:text="@string/settings_btn"
       android:textColor="#ffffff"
       android:textSize="20sp"
       app:layout_constraintRight_toRightOf="parent"
       app:layout_constraintTop_toTopOf="parent"/>
  1. เปิด nav_graph.xml
  2. เพิ่มการดำเนินการภายใน mainFragment id ของการดำเนินการคือ action_mainFragment_to_customizeFragment และปลายทางคือ customizeFragment

nav_graph.xml

<fragment
       android:id="@+id/mainFragment"
       android:name="com.example.android.firebaseui_login_sample.MainFragment"
       android:label="MainFragment">
   <action
           android:id="@+id/action_mainFragment_to_settingsFragment"
           app:destination="@id/settingsFragment"/>
</fragment>
  1. เปิด MainFragment.kt
  2. ใน onViewCreated() ให้ตั้งค่า onClickListener สำหรับ settings_btn เพื่อให้การแตะปุ่มนำผู้ใช้ไปยัง customizeFragment

MainFragment.kt

binding.settingsBtn.setOnClickListener {
   val action = MainFragmentDirections.actionMainFragmentToSettingsFragment()
   findNavController().navigate(action)
}
  1. หากเห็นข้อผิดพลาดที่ยังไม่ได้รับการแก้ไข ให้คอมไพล์แอปอีกครั้งจากเมนูสร้างเพื่อสร้างและใช้การดำเนินการนำทางใหม่ที่คุณสร้างขึ้น
  2. เปิดแอปอีกครั้ง ตอนนี้ควรมีปุ่มการตั้งค่าที่ใช้งานได้ที่มุมขวาบน
  3. คลิกปุ่มที่จะนำคุณไปยังหน้าจอการตั้งค่า หน้าจอการตั้งค่ามีเพียงตัวเลือกเดียวคืออนุญาตให้ผู้ใช้เลือกประเภทข้อเท็จจริงที่น่าสนใจที่ต้องการให้แสดงบนหน้าจอหลัก
  4. คลิกปุ่มย้อนกลับของอุปกรณ์ Android เพื่อกลับไปที่หน้าจอหลัก

ในงานนี้ คุณจะเพิ่มโค้ดเพื่อนำผู้ใช้ไปยังหน้าจอเข้าสู่ระบบหากผู้ใช้พยายามเข้าถึงหน้าจอการตั้งค่าในขณะที่ไม่ได้เข้าสู่ระบบ

  1. เปิด SettingsFragment.kt
  2. ใน onViewCreated() ให้สังเกต authenticationState และเปลี่ยนเส้นทางผู้ใช้ไปยัง LoginFragment หากผู้ใช้ไม่ได้รับการตรวจสอบสิทธิ์

SettingsFragment.kt

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
   super.onViewCreated(view, savedInstanceState)
   val navController = findNavController()
   viewModel.authenticationState.observe(viewLifecycleOwner, Observer { authenticationState ->
       when (authenticationState) {
           LoginViewModel.AuthenticationState.AUTHENTICATED -> Log.i(TAG, "Authenticated")
           // If the user is not logged in, they should not be able to set any preferences,
           // so navigate them to the login fragment
           LoginViewModel.AuthenticationState.UNAUTHENTICATED -> navController.navigate(
               R.id.loginFragment
           )
           else -> Log.e(
               TAG, "New $authenticationState state that doesn't require any UI change"
           )
       }
   })
}

เนื่องจากแอปจะนำผู้ใช้ไปยังหน้าจอเข้าสู่ระบบหากผู้ใช้พยายามเข้าถึงหน้าจอการตั้งค่า แอปจึงต้องจัดการลักษณะการทำงานของปุ่มย้อนกลับในหน้าจอเข้าสู่ระบบด้วย หากแอปไม่ได้ปรับแต่งการจัดการลักษณะการทำงานของปุ่มย้อนกลับ ผู้ใช้จะติดอยู่ในลูปที่ไม่มีที่สิ้นสุดของการพยายามกลับไปที่หน้าจอการตั้งค่า แต่ระบบจะเปลี่ยนเส้นทางไปยังหน้าจอเข้าสู่ระบบอีกครั้ง

  1. เปิด LoginFragment.kt
  2. ใน onViewCreated() ให้จัดการการดำเนินการของปุ่มย้อนกลับโดยนำผู้ใช้กลับไปที่ MainFragment

LoginFragment.kt

// If the user presses the back button, bring them back to the home screen
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
   navController.popBackStack(R.id.mainFragment, false)
}
  1. เปิดแอปอีกครั้งและยืนยันว่าหากคุณไม่ได้เข้าสู่ระบบ ระบบจะเปลี่ยนเส้นทางความพยายามในการเข้าถึงหน้าจอการตั้งค่าไปยังขั้นตอนการเข้าสู่ระบบ

แม้ว่าคุณจะเปลี่ยนเส้นทางผู้ใช้ให้เข้าสู่ระบบได้สำเร็จ แต่คุณยังไม่ได้จัดการสิ่งที่เกิดขึ้นหลังจากที่ผู้ใช้เข้าสู่ระบบสำเร็จ ดังนั้นการพยายามเข้าสู่ระบบจะดูเหมือนว่าไม่ทำงาน คุณจะแก้ไขปัญหานี้ได้ในขั้นตอนถัดไป

ตอนนี้คุณตั้งค่าแอปให้เปลี่ยนเส้นทางผู้ใช้ไปยังหน้าจอเข้าสู่ระบบได้สำเร็จแล้ว หากผู้ใช้พยายามเข้าถึงหน้าจอการตั้งค่าโดยที่ไม่ได้เข้าสู่ระบบ

อย่างไรก็ตาม หลังจากที่คุณทำตามขั้นตอนการลงชื่อเข้าใช้แล้ว ระบบจะนำคุณกลับไปที่หน้าจอเข้าสู่ระบบอีกครั้ง ซึ่งจะทำให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ไม่ดีและอาจสับสนได้

แอปควรนำผู้ใช้กลับไปที่หน้าจอการตั้งค่าหลังจากที่ผู้ใช้เข้าสู่ระบบสำเร็จ เพื่อมอบประสบการณ์การใช้งานที่ดียิ่งขึ้น

  1. ใน LoginFragment.kt ที่ใดก็ได้ใน onViewCreated() ให้สังเกต authenticationState และนำผู้ใช้กลับไปที่ SettingsFragment เมื่อตรวจสอบสิทธิ์สำเร็จ

LoginFragment.kt

// Observe the authentication state so we can know if the user has logged in successfully.
// If the user has logged in successfully, bring them back to the settings screen.
// If the user did not log in successfully, display an error message.
viewModel.authenticationState.observe(viewLifecycleOwner, Observer { authenticationState ->
   when (authenticationState) {
      // Since our login flow is only one screen instead of multiple 
      // screens, we can utilize popBackStack(). If our login flow 
      // consisted of multiple screens, we would have to call 
      // popBackStack() multiple times.
       LoginViewModel.AuthenticationState.AUTHENTICATED -> navController.popBackStack()
       else -> Log.e(
           TAG,
           "Authentication state that doesn't require any UI change $authenticationState"
       )
   }
})
  1. เรียกใช้แอปอีกครั้งและยืนยันว่าเมื่อลงชื่อเข้าใช้สำเร็จ คุณจะไปที่หน้าการตั้งค่าแทนหน้าเข้าสู่ระบบ

คุณสามารถดูแอปฉบับสมบูรณ์พร้อมโค้ดโซลูชันทั้งหมดได้ที่ที่เก็บข้อมูล Github https://github.com/googlecodelabs/android-kotlin-login-navigation

ใน Codelab นี้ คุณได้เรียนรู้แนวทางปฏิบัติแนะนำเกี่ยวกับวิธีสร้างประสบการณ์ของผู้ใช้ที่ดีในแอปที่รองรับการเข้าสู่ระบบ การสังเกตสถานะการตรวจสอบสิทธิ์ของแอปช่วยให้คุณระบุได้ว่าผู้ใช้เข้าถึงหน้าจอใดได้บ้าง และเปลี่ยนเส้นทางผู้ใช้ไปยังหน้าจอเข้าสู่ระบบเมื่อจำเป็น

ดูข้อมูลเพิ่มเติมเกี่ยวกับแนวทางปฏิบัติแนะนำในการนำทางใน Android ได้ที่แหล่งข้อมูลต่อไปนี้

เอกสารประกอบสำหรับนักพัฒนาแอป Android

Codelabs:

ดูลิงก์ไปยัง Codelab อื่นๆ ในหลักสูตรนี้ได้ที่หน้า Landing Page ของ Codelab Android ขั้นสูงใน Kotlin