为什么在Android中使用后退按钮(物理后退按钮)后无法更改工具栏标题?

为什么在Android中使用后退按钮(物理后退按钮)后无法更改工具栏标题?,android,android-architecture-components,android-jetpack,android-architecture-navigation,android-jetpack-navigation,Android,Android Architecture Components,Android Jetpack,Android Architecture Navigation,Android Jetpack Navigation,以下是要下载的项目: 我正在使用Android导航组件,下面是应用程序的屏幕截图: 如您所见,在MainActivity布局中,有一个导航主机片段、一个工具栏和一个底部导航视图 蓝色标签的顺序在图中是这样的 工具栏自定义标题中的标题在目的地\u blue1片段中硬编码 class Blue1Fragment : Fragment() { lateinit var moveButton: Button lateinit var fragmentView: View ov

以下是要下载的项目:

我正在使用Android导航组件,下面是应用程序的屏幕截图:

如您所见,在MainActivity布局中,有一个导航主机片段、一个工具栏和一个底部导航视图

蓝色标签的顺序在图中是这样的

工具栏自定义标题中的标题在目的地\u 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
    }


}
但是当我从blue1移动到blue2,然后使用back按钮physhical hardware back按钮返回blue1时,标题将更改为fragment_blue1,而不是这里硬编码的自定义标题

片段_blue1实际上是该片段的目标图id的字符串

我不明白为什么即使我在这里硬编码标题为自定义标题,但如果我使用physhical hardware back按钮,它就是不起作用

但是,如果我使用工具栏/操作栏中的up button back按钮,那么标题将是根据我硬编码的标题在这里定制的标题

这是当我的硬编码标题不起作用时的标题,当我使用后退按钮物理后退按钮从蓝色2移回蓝色1时的标题

这是我真实案例的简化,我需要从片段Blue1动态更改标题。我不明白为什么使用“后退”按钮后不能更改标题。但当使用up按钮时,标题将按照我使用的代码显示,与目标id图不同

如何解决这个问题?出了什么问题

我正在使用style,这是我主要活动的代码

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动态更改,您可以传递捆绑包上的标题,并将其替换为自定义标题

//inside Blue2Fragment

override fun onStop() {
    (activity as AppCompatActivity).supportActionBar?.title = "CUSTOM TITLE HERE"
    super.onStop()
}
我不熟悉kotlin,但这里有一个java解决方案,它通过动态更改工具栏的标题和副标题来解决这个问题

首先,我们需要创建一个对象,作为带有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中,我们将工具栏定义为MultableLiveData,并在onCreate中观察它,在onDestroy中删除观察者

还要从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" />

我希望有帮助

非常感谢,但不幸的是它不起作用。我也试着把它移到onResume上,但仍然不起作用。非常感谢,但不幸的是,它不起作用。我已经试着在Blue2Fragment中放上这个桌面代码:@Alexa289当你关闭Blue2Fragment onStop调用时,你可以在销毁片段之前设置标题,我认为你应该在第一个片段中实现,或者也可以尝试暂停,但这没有任何意义。我已经试过了,效果很好,非常感谢你的回复。应该在这个时候实施,对吗。如果是,那么不幸的是它仍然不起作用。如果我使用右下角的后退按钮,标题仍然不是自定义标题。如果您不介意,您可以通过我的dropbox链接下载上述项目:
@Override
public void onStart() {
    super.onStart();
    ((MainActivity) requireActivity()).toolbar.postValue(new Toolbar("MyFragment Title", null));
}
<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" />