iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

0
自我挑戰組

練習程式系列 第 36

Android,Navigation、Fragment

主要是在練習:
Jetpack Navigation Component in One Video
Android Navigation 學習筆記(一) 基礎使用
整理

1

Navigation非常方便,所以就先嘗試一個activity,多個fragment。
popUpTo應該會常用到,目前用到就是,如果相機突然沒有相機權限,就先回到permissionsFragment要權限,取得權限後再回到相機,但是這時候相機按返回鍵又會回到permissionsFragment,所以需要:

app:popUpTo="@id/permissionsFragment"
app:popUpToInclusive="true"

2

帳號如果要登出,就會回到登入頁面,然後登入頁面按返回鍵要回到桌面(關掉app),不能回到原本有帳號的畫面。
使用navController,先清空Fragment,再到loginFragment(登入頁面)

var navController= findNavController(this,R.id.host_fragment)
navController.popBackStack(R.id.loginFragment, true)
navController.navigate(R.id.loginFragment)

參考:How to clear navigation Stack after navigating to another fragment in Android
解答3

3

如何修改fragment的標題列(toolbar)?
在特定的fragment,改變activity的標題列(toolbar)?
參考:2 different ways to inflate menu for Toolbar inside Activity and Fragment

在Navigation,目前是一個activity,多個fragment。所以標題列的修改在MainActivity修改就好了,不用寫在個別fragement:
參考:android hide toolbar in specific fragment
解答四(不過好像只是讓toolbar消失而已,還要在試試能不能換另一個toolbar):

.addOnDestinationChangedListener

4

Avoiding Android navigation IllegalArgumentException in NavController
這個問題好像是因為按鈕連按兩次?就是重複了兩次navigate到某一個fragment
解決方法-->參考解答1:
用.currentDestination檢查現在是不是在當前fragment:

.currentDestination

5

fragment的setContentView:
android-fragments - Android: Fragment: setContentView的替代品

6

如何用一個按鈕,點擊之後,回到上一個fragment?(不是直接點手機的返回鍵)

How to return to Previous Fragment by clicking back(Not Hardware back button)?

Navigation.findNavController(requireActivity(), R.id.nav_host_fragment).popBackStack()

7

如何在Fragment使用activity的toolbar(標題列)???

toolbar menu item click in fragments
解答2:
一 fragment implements interface:

implements Toolbar.OnMenuItemClickListener

二 然後再activity修改,讓Fragment的toolbar(標題列)的功能和畫面消失:
覆寫onPrepareOptionsMenu
使用menu?.clear();

override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
        var navController= findNavController(this,R.id.nav_host_fragment)
        navController.addOnDestinationChangedListener(NavController.OnDestinationChangedListener { controller, destination, arguments ->
            if (destination.id == R.id.Fragment) {
                //先清空,不然會一直疊加
                menu?.clear();
            }
            else {
                //先清空,不然會一直疊加
                menu?.clear();
                getMenuInflater().inflate(R.menu.all_menu, menu);
                return@OnDestinationChangedListener
            }
        })
        return super.onCreateOptionsMenu(menu);
}

然後再addOnDestinationChangedListener修改toolbar,toolbar再修改點擊事件:

        navController.addOnDestinationChangedListener(NavController.OnDestinationChangedListener { controller, destination, arguments ->
            if (destination.id == R.id.Fragment) {
            
            }
            }
            else {
                toolbar.setVisibility(View.VISIBLE)
                toolbar.setOnMenuItemClickListener {
                    if (it.itemId == R.id.menu_logout) { //其他頁面的登出按鈕
                        Toast.makeText(this, "登出", Toast.LENGTH_LONG).show()
                        navController.popBackStack(R.id.loginFragment, true)
                        navController.navigate(R.id.loginFragment)
                    }
                    true
                }
            }
        })

後來找到:不用使用avtivity的toolbar

navigationview with different toolbar for each fragment

就是在特定fragment,也自己放一個toolbar到xml檔,然後隱藏activity的toolbar,顯示fragment自己的toolbar。
特定的fragment在自己處理自己的toolbar,不用使用avtivity的toolbar。

8

在特定的fragment,不橫屏:
解答2:
Allow rotation/landscape in one fragment

9

Why getContext() in fragment sometimes returns null?

Fragment: getContext vs requireContext


上一篇
js 筆記
系列文
練習程式36

尚未有邦友留言

立即登入留言