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

时间:2019-11-29 01:41:10

标签: android android-architecture-components android-jetpack android-architecture-navigation android-jetpack-navigation

这是要下载的项目:https://www.dropbox.com/s/lq3p2pnwjacik7s/testApp.zip?dl=0

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

enter image description here

如您所见,在MainActivity布局中,有一个nav_host_fragment,一个工具栏和一个底部导航视图。

和“蓝色标签”的顺序将在图中类似

enter image description here

工具栏“此处的自定义标题”中的标题硬编码在destination_blue1片段中

但是当我从blue1移到blue2,然后使用后退按钮(物理硬件后退按钮)返回到blue1时,标题然后更改为“ fragment_blue1”,而不是“ CUSTOM TITLE HERE”(硬编码)。

“ fragment_blue1”实际上是该片段的目标图ID的字符串。

我不明白为什么即使我将标题硬编码为“ CUSTOM TITLE HERE”,但如果我使用(物理硬件后退按钮),就无法使用。

但是,如果我使用向上按钮(工具栏/操作栏中的后退按钮),那么根据我硬编码的标题,标题将为“ CUSTOM TITLE HERE”。

当我使用后退按钮(物理后退按钮)从blue 2移回blue1时,当我的硬编码标题不起作用时,这是标题。

enter image description here

这是我实际情况的简化,我需要从片段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)
    }


}

3 个答案:

答案 0 :(得分:0)

尝试在“ onViewCreated”中设置标题

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)


}

答案 1 :(得分:0)

之所以会这样,是因为您添加了片段,而添加了onResume却没有调用。如果您的导航很简单(片段之间的路由始终相同),则可以通过调用SecondFragment中的onStop()来实现它,并在此方法内部将工具栏标题更改为第一个片段标题。 如果您的片段动态变化(从fr1调用fr2 / fr3),则可以在包中传递标题,并将其替换为自定义标题

//inside Blue2Fragment

override fun onStop() {
    (activity as AppCompatActivity).supportActionBar?.title = "CUSTOM TITLE HERE"
    super.onStop()
}

答案 2 :(得分:0)

我不熟悉kotlin,但是java中提供了一种变通方法,它通过更改toolbar的{​​{1}}和{{1}来解决此问题。 }。

首先,我们需要创建一个对象,用作带有标题和字幕参数的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)); } ,以避免标题/标签冲突。

android:label

希望对您有帮助!