[英]why I can't change toolbar title after using back button (physical back button) in Android?
這是要下載的項目: https ://www.dropbox.com/s/lq3p2pnwjacik7s/testApp.zip?dl=0
我正在使用 Android 導航組件,這是應用程序的屏幕截圖:
如您所見,在 MainActivity 布局中,有一個 nav_host_fragment、一個工具欄和一個底部導航視圖。
Blue Tab 的順序在圖中將是這樣的
工具欄中的標題“CUSTOM TITLE HERE”硬編碼在 destination_blue1 片段中
但是當我從 blue1 移動到 blue2,然后使用后退按鈕(物理硬件后退按鈕)返回 blue1 時,標題會更改為“fragment_blue1”,而不是“CUSTOM TITLE HERE”(硬編碼)。
“fragment_blue1”實際上是該片段的目標圖 ID 字符串。
我不明白為什么即使我將標題硬編碼為“CUSTOM TITLE HERE”,如果我使用(物理硬件后退按鈕)它也不起作用。
但是,如果我使用向上按鈕(工具欄/操作欄中的后退按鈕),則標題將根據我硬編碼的標題為“CUSTOM TITLE HERE”。
這是當我的硬編碼標題不起作用時的標題,當我使用后退按鈕(物理后退按鈕)從藍色 2 回到藍色 1 時。
這是我真實案例的簡化,我需要從片段 Blue1 動態更改標題。 我不明白為什么我在使用后退按鈕后無法更改標題。 但是當使用向上按鈕時,標題將按照我使用的代碼顯示,與目的地 ID 圖不同。
如何解決這個問題? 什么地方出了錯?
我正在使用樣式<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
這是我的 MainActivity 的代碼
class MainActivity : AppCompatActivity() {
lateinit var navController : NavController
lateinit var toolbar: Toolbar
lateinit var bottomNavigationView : BottomNavigationView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
navController = Navigation.findNavController(this,R.id.nav_host_fragment)
setUpViewDeclaration()
setupBottomNavMenu()
setupActionBar()
}
private fun setUpViewDeclaration() {
toolbar = findViewById(R.id.toolbar)
bottomNavigationView = findViewById(R.id.bottom_nav)
}
private fun setupBottomNavMenu() {
bottom_nav.setupWithNavController(navController)
}
private fun setupActionBar() {
// set up top hierarchy destination
val appBarConfiguration = AppBarConfiguration(setOf(
R.id.destination_blue1,
R.id.destination_red1)
)
setSupportActionBar(toolbar)
toolbar.setupWithNavController(navController,appBarConfiguration)
}
}
這是 blue1 片段的代碼
class Blue1Fragment : Fragment() {
lateinit var moveButton: Button
lateinit var fragmentView: View
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
fragmentView = inflater.inflate(R.layout.fragment_blue1, container, false)
moveButton = fragmentView.findViewById(R.id.move_button_1)
// The title hard coded in here
// this one line below seems doesn't work if using back physical button
(activity as AppCompatActivity).supportActionBar?.title = "CUSTOM TITLE HERE"
moveButton.setOnClickListener {
val nextDestination = Blue1FragmentDirections.actionToBlue2()
Navigation.findNavController(fragmentView).navigate(nextDestination)
}
return fragmentView
}
}
這是 blue2 片段的代碼:
class Blue2Fragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blue2, container, false)
}
}
嘗試在“onViewCreated”中設置標題
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
發生這種情況是因為您添加了片段,同時添加了 onResume 而不是調用。 如果您的導航很簡單(片段之間的路由始終相同),您可以通過在 SecondFragment 中調用 onStop() 並在此方法內將工具欄標題更改為第一個片段標題來實現它。 如果您的片段動態變化(從 fr1 調用 fr2/fr3),您可以在 bundle 上傳遞標題並將其替換為您的自定義標題
//inside Blue2Fragment
override fun onStop() {
(activity as AppCompatActivity).supportActionBar?.title = "CUSTOM TITLE HERE"
super.onStop()
}
我不熟悉kotlin
,但是這里有一個java
解決方法,通過動態更改toolbar
的title
和subTitle
標題來解決這個問題。
首先,我們需要創建一個對象,用作帶有標題和副標題參數的MultableLiveData
類型。
public class Toolbar {
private String title, subTitle;
public Toolbar(String title, @Nullable String subTitle) {
this.title = title;
this.subTitle = subTitle;
}
public String getTitle() {
return title;
}
public String getSubTitle() {
return subTitle;
}
}
在MainActivity
中,我們將toolbar
定義為MultableLiveData
並在onCreate()
中觀察它並在onDestroy()
中移除觀察者。
public MutableLiveData<Toolbar> toolbar = new MutableLiveData<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bottomNavigationView = (BottomNavigationView) findViewById(R.id.main_bottomnav);
navigationView = (NavigationView) findViewById(R.id.main_sidebar);
drawerLayout = (DrawerLayout) findViewById(R.id.main_drawer);
setupNavigation();
toolbar.observe(this, new Observer<Toolbar>() {
@Override
public void onChanged(Toolbar toolbarModel) {
getSupportActionBar().setTitle(toolbarModel.getTitle());
getSupportActionBar().setSubtitle(toolbarModel.getSubTitle());
}
});
}
@Override
protected void onDestroy() {
toolbar.removeObservers(this);
super.onDestroy();
}
在您的任何片段中,我們將toolbar
的標題和副標題設置如下:
@Override
public void onStart() {
super.onStart();
((MainActivity) requireActivity()).toolbar.postValue(new Toolbar("MyFragment Title", "MyFragment SubTitle"));
}
要么
@Override
public void onStart() {
super.onStart();
((MainActivity) requireActivity()).toolbar.postValue(new Toolbar("MyFragment Title", null));
}
還要從nav_graph.xml
中刪除android:label
以避免標題/標簽沖突。
<fragment
android:id="@+id/shopFragment"
android:name="com.myapp.ShopFragment"
android:label="TO BE REMOVED" // REMOVE THIS LINE OF CODE
tools:layout="@layout/fragment_shop" />
我希望它有所幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.