希望大家都平安。在使用 ActionBar 中的 ActionBar 和 Up 按鈕時,我遇到了一個令人沮喪的問題。我的應用程式中有以下片段結構:
MainFragment -
|- SettingsFragment -
|- GeneralSettingsFragment
|- ScaryStuffSettingsFragment
上面的所有片段都啟用了 ActionBar。SettingsFragment、GeneralSettingsFragment 和 ScaryStuffFragment 都啟用了向上按鈕,以便用戶可以在需要時按上述順序回傳。
在我的 MainFragment 中,我有以下代碼可以訪問 SettingsFragment:
override fun onOptionsItemSelected(item: MenuItem): Boolean {
super.onOptionsItemSelected(item)
when(item.itemId) {
R.id.action_main_to_settings_menu -> {
onOptionSettingsClick()
}
}
return true
}
/** When the user taps the options menu settings button, we'll take them to the
* settings menu.
*/
private fun onOptionSettingsClick() {
findNavController().navigate(R.id.settingsFragment)
}
在我的 SettingsFragment 中,我有以下內容:
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when(item.itemId) {
android.R.id.home -> findNavController().navigateUp()
}
return super.onOptionsItemSelected(item)
}
SettingsFragment 中使用的代碼與 ScaryStuffSettingsFragment 和 GeneralSettingsFragment 中使用的代碼相同。
現在,當我點擊 MainFragment 中的設定時,它會將我帶到 SettingsFragment。那里沒有問題。如果我點擊 SettingsFragment ActionBar 中的向上按鈕,同樣,它會將我發送到 MainFragment。
如果我點擊可怕的東西或一般設定,它會帶我到相關的片段沒有問題。如果我點擊任一片段中的向上按鈕,它會將我帶到 SettingsFragment。再次。這里沒有問題。
但是,如果我想在使用向上按鈕點擊可怕的東西或常規后從 SettingsFragment 回傳 MainFragment ......什么也沒有發生。
我發現,如果我點擊設備本身的后退按鈕,它會帶我回到 MainFragment 完全規避問題,但我不希望用戶在大多數設定中使用向上按鈕然后有點擊后退按鈕(如果有意義的話)。
一旦選擇了其中一個子片段,這里會發生什么“忘記” MainFragment 和 SettingsFragment 之間的傳輸?
謝謝!
編輯:
MainFragment 是一個普通的片段。它的onCreateView如下:
override fun onCreateView(inflater: LayoutInflater,
container: ViewGroup?,
savedInstance: Bundle?): View {
_binding = FragmentMainBinding.inflate(inflater, container, false)
setHasOptionsMenu(true)
return binding.root
}
我的所有三個設定應用程式都是 PreferenceFragments,因此具有以下內容:
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.general_settings_preferences, rootKey)
setHasOptionsMenu(true)
}
編輯2:
我現在有以下內容:
主要活動:
override fun onCreate(savedInstanceState: Bundle?) {
navController = findNavController(R.id.nav_host)
appBarConfiguration = AppBarConfiguration.Builder(R.id.FragmentMain).build()
val hostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment_container) as NavHostFragment?
//navController = hostFragment?.navController!! // Commented out due to throwing a nullpointerexception
setupActionBarWithNavController(navController, appBarConfiguration)
}
override fun onSupportNavigateUp(): Boolean {
return (NavigationUI.navigateUp(navController, appBarConfiguration) || super.onSupportNavigateUp())
}
當我這樣做時(并更新我的導航圖),然后點擊設定(轉到我的 SettingsFragment)它會短暫顯示 SettingsFragment 然后更改為頂部的設定(這是因為我(activity as AppCompatActivity).supportActionBar?.title = getString(R.string.menu_option_settings)在我的onCreateOptionsMenu方法中告訴它。然后, 當我點擊回傳時, 這會按預期作業. 但是, 當我然后點擊可怕的東西 (去 ScaryStuffSettingsFragment) 或常規設定 (去 GeneralSettingsFragment) 它做同樣的事情并在頂部閃爍片段的名稱,然后更改為我設定的內容,當我點擊向上箭頭時,它會將我發送回主片段。
我只希望設定選單回傳到 MainFragment,其他設定應該轉到設定選單(如果有意義的話)。
uj5u.com熱心網友回復:
如果我想在我使用向上按鈕點擊可怕的東西或常規后從 SettingsFragment 回傳 MainFragment ......沒有任何反應。
沒有任何反應意味著導航組件沒有管理 UP 按鈕的點擊;顯然您按照以下方式手動管理后臺導航:
override fun onOptionsItemSelected(item: MenuItem): Boolean { when(item.itemId) { android.R.id.home -> findNavController().navigateUp() } return super.onOptionsItemSelected(item) }
為了解決這個問題,請確保supportActionBar在托管這些片段的活動中添加啟用導航(檔案參考):
- 呼叫 setupActionBarWithNavController()
- 覆寫
onSupportNavigateUp()
class MainActivity : AppCompatActivity() {
lateinit var navController: NavController
private lateinit var mAppBarConfiguration: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mAppBarConfiguration = AppBarConfiguration.Builder(
R.id.main_fragment // Adjust that to your top level fragments (that you don't want the UP button appear)
).build()
val hostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment1) as NavHostFragment?
navController = hostFragment?.navController!!
setupActionBarWithNavController(this, navController)
}
override fun onSupportNavigateUp(): Boolean {
return (NavigationUI.navigateUp(navController, mAppBarConfiguration)
|| super.onSupportNavigateUp())
}
}
注意:如果您不使用默認的supportActionBar,啟用導航組件控制元件您的自定義工具列:
toolbar.setupWithNavController(navController, appBarConfiguration)
到目前為止,這使得actionBar& 其導航由導航組件/ 控制navController。并且通過UP按鈕的導航將正常注冊到backstack中。
但是要從任何導航操作的回傳堆疊中洗掉一些片段,您可以使用popUpTo &popUpToInclusive。這個答案用一個例子描述了差異。
將其應用于您的案例;你可以通過 from SettingsFragmentto GeneralSettingsFragment|的動作來做到這一點ScaryStuffSettingsFragment
無論是在navGraph:
<navigation ...>
....
<fragment
android:id="@ id/fragmentSettings"
android:name="com.example.android.ktnavarchcomptwoactivities.SettingsFragment"
android:label="fragmentSettings" >
<action
android:id="@ id/action_fragmentSettings_to_fragmentScaryStuffSettings"
app:destination="@id/fragmentScaryStuffSettings"
app:popUpTo="@id/fragment_main"
app:popUpToInclusive="false"/>
<action
android:id="@ id/action_fragmentSettings_to_fragmentGeneralSettings"
app:destination="@id/fragmentGeneralSettings"
app:popUpTo="@id/fragment_main"
app:popUpToInclusive="false"/>
</fragment>
</navigation>
NavOptions或者通過在導航期間定義引數以編程方式:
在 SettingsFragment 中:
// Navigation from SettingsFragment to GeneralSettingsFragment
findNavController().navigate(
R.id.action_fragmentSettings_to_fragmentGeneralSettings,
null,
NavOptions.Builder().setPopUpTo(R.id.fragment_main, false).build()
)
// Navigation from SettingsFragment to ScaryStuffSettingsFragment
findNavController().navigate(
R.id.action_fragmentSettings_to_fragmentScaryStuffSettings,
null,
NavOptions.Builder().setPopUpTo(R.id.fragment_main, false).build()
)
uj5u.com熱心網友回復:
將 setHasOptionsMenu 添加到 onViewCreated
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setHasOptionsMenu(true)
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/411999.html
標籤:
