這個程式碼研究室是「Android Kotlin 進階功能」課程的一部分。如果您按部就班完成每一堂程式碼研究室課程,就能充分體驗到本課程的價值,但這不是強制要求。如要查看所有課程程式碼研究室,請前往 Android Kotlin 進階功能程式碼研究室登陸頁面。
本程式碼研究室是「在 Android 上使用 FirebaseUI 實作登入功能」的延伸內容。如果您尚未完成先前的程式碼研究室,可以下載本程式碼研究室的範例程式碼,但建議您先完成「使用 FirebaseUI 在 Android 上實作登入功能」程式碼研究室。
簡介
如果應用程式支援登入功能,常見的用途是僅供已登入的使用者存取部分內容。舉例來說,您可能想為已登入的使用者保留應用程式的「設定」畫面。
在這種情況下,您可以根據使用者的驗證狀態,使用條件式導覽將使用者帶往適當的畫面。
在本程式碼研究室中,您將以現有應用程式為基礎,新增設定畫面,只有登入的使用者才能存取。您將使用 Android 的導覽元件完成這項工作。
必備知識
- Android 的 Navigation 元件,以及如何在 Android 應用程式中使用
- 如何使用 FirebaseUI 程式庫,在 Android 應用程式中實作登入功能。如果您不熟悉這個概念,請完成「 使用 FirebaseUI 在 Android 上導入登入功能」程式碼研究室。
課程內容
- 如何根據使用者是否已登入,將他們導向應用程式的適當畫面。
學習內容
- 在使用者成功登入後,正確處理將使用者導覽至正確畫面的程序。
- 如果使用者未登入,請禁止他們存取「設定」畫面,並將他們重新導向至「登入」畫面。
在先前的程式碼研究室中,您開發的應用程式會顯示 Android 相關事實。您的應用程式也允許使用者登入及登出。在本程式碼實驗室中,您將在現有應用程式中新增設定畫面。使用者必須登入才能存取設定畫面。
如果使用者未登入,嘗試存取設定畫面時,應用程式會將他們重新導向至登入畫面。登入程序完成後,使用者會返回原本嘗試存取的設定畫面。

本程式碼研究室是「在 Android 上使用 FirebaseUI 實作登入功能」的延伸內容。如果您尚未完成先前的程式碼研究室,可以下載本程式碼研究室的範例程式碼,但建議您先完成「使用 FirebaseUI 在 Android 上實作登入功能」程式碼研究室。
下載範例應用程式,方法如下:
... 或使用下列指令從指令列複製 GitHub 存放區,並切換至存放區的 start 分支:
$ git clone https://github.com/googlecodelabs/android-kotlin-login-navigation
在 Android Studio 中載入專案後,請按照下列步驟操作:
- 在模擬器或實體裝置上執行應用程式,確認環境已成功設定,可以開始開發。
如果成功,主畫面會顯示有趣的 Android 知識,左上角則會顯示登入按鈕。
入門應用程式的現有功能:
- 如果使用者未登入,輕觸「登入」按鈕會啟動登入流程,讓使用者透過電子郵件地址或 Google 帳戶登入。
- 如果使用者已登入,按鈕會變更為「登出」按鈕,方便使用者登出。
在這項工作中,您會在主畫面上新增按鈕,讓使用者前往設定畫面。使用者可以在設定畫面中選擇要在主畫面上顯示哪種有趣的事實。在設定畫面中,他們可以選擇查看 Android 或加州相關事實。

- 開啟
fragment_main.xml。 - 在
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"/>- 開啟
nav_graph.xml。 - 在
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>- 開啟
MainFragment.kt。 - 在
onViewCreated()中,為settings_btn設定onClickListener,讓使用者輕觸按鈕時,系統會將使用者導向至customizeFragment。
MainFragment.kt
binding.settingsBtn.setOnClickListener {
val action = MainFragmentDirections.actionMainFragmentToSettingsFragment()
findNavController().navigate(action)
}- 如果看到未解決的錯誤,請從「Build」選單重新編譯應用程式,以產生並使用您建立的新導覽動作。
- 重新啟動應用程式。現在右上角應該會有可用的「設定」按鈕。
- 按一下按鈕,系統應會將你帶往「設定」畫面。「設定」畫面只有一個選項,可讓使用者選擇要在主畫面顯示哪種有趣的事實。
- 按一下 Android 裝置的返回按鈕,返回主畫面。

在這項工作中,您會新增程式碼,讓使用者在未登入時嘗試存取設定畫面時,系統會將他們導向登入畫面。
- 開啟
SettingsFragment.kt。 - 在
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"
)
}
})
}由於使用者嘗試存取設定畫面時,應用程式會將使用者帶往登入畫面,因此應用程式也必須處理登入畫面上的返回按鈕行為。如果應用程式未自訂返回按鈕的處理行為,使用者會陷入無限迴圈,嘗試返回設定畫面,但隨即又會重新導向至登入畫面。
- 開啟
LoginFragment.kt。 - 在
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)
}- 重新啟動應用程式,確認如果未登入,嘗試存取設定畫面時,系統會將您重新導向登入流程。
您已成功將使用者重新導向至登入畫面,但尚未處理使用者成功登入後的情況,因此登入嘗試會顯示為無效。您將在下一個步驟中修正這個問題。
到目前為止,您已成功設定應用程式,如果使用者嘗試存取設定畫面但未登入,系統會將他們重新導向至登入畫面。
不過,完成登入流程後,系統會再次將你帶回登入畫面。這無法提供良好的使用者體驗,且可能會造成混淆。
為提供理想的使用者體驗,應用程式應在使用者成功登入後,將使用者帶回設定畫面。
- 仍在
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"
)
}
})- 再次執行應用程式,確認現在成功登入後,您會前往「設定」頁面,而不是「登入」頁面。
如要查看包含所有解決方案程式碼的完整應用程式,請前往這個 GitHub 存放區:https://github.com/googlecodelabs/android-kotlin-login-navigation。
在本程式碼研究室中,您已瞭解如何採用最佳做法,在支援登入的應用程式中打造優質的使用者體驗。觀察應用程式的驗證狀態後,您就能判斷使用者可存取哪些畫面,並在必要時將他們重新導向至登入畫面。
如要進一步瞭解 Android 導覽的最佳做法,請參閱下列資源:
Android 開發人員說明文件:
Codelabs:
如要查看本課程其他程式碼研究室的連結,請參閱 Android Kotlin 進階功能程式碼研究室登陸頁面。