导航抽屉backstack,如何让actionbar标题在点击后随片段改变

Posted

技术标签:

【中文标题】导航抽屉backstack,如何让actionbar标题在点击后随片段改变【英文标题】:Navigation drawer backstack, how to get the actionbar title to change with fragment on back click 【发布时间】:2018-05-26 20:19:35 【问题描述】:

所以我设法让一个库存导航抽屉工作,并且操作栏标题随着所选片段而改变。我还设法让 backstack 轻松工作。

我不知道该怎么做是通过单击返回来更改操作栏标题。谷歌文档说要添加一个 onBackStackChangedListener:

getSupportFragmentManager().addOnBackStackChangedListener(
        new FragmentManager.OnBackStackChangedListener() 
            public void onBackStackChanged() 
                // Update your UI here.
            
        );

但我不知道该把它放在哪里?他们说当我 .commit 进行更改时,所以我认为它是放在

之后
if (id == R.id.nav_spatial_awareness) 
            setTitle("Spatial Awareness");
            SpatialAwareness spatialAwarenessFragment = new SpatialAwareness();
            android.support.v4.app.FragmentManager spatialAwarenessManager = getSupportFragmentManager();
            spatialAwarenessManager.beginTransaction()
                    .addToBackStack(null)
                    .replace(R.id.main_content_layout, spatialAwarenessFragment, spatialAwarenessFragment.getTag())
                    .commit();

但这没有用,这是我尝试过的,我得到的只是红色的波浪线

if (id == R.id.nav_spatial_awareness) 
            setTitle("Spatial Awareness");
            SpatialAwareness spatialAwarenessFragment = new SpatialAwareness();
            android.support.v4.app.FragmentManager spatialAwarenessManager = getSupportFragmentManager();
            spatialAwarenessManager.beginTransaction()
                    .addToBackStack(null)
                    .replace(R.id.main_content_layout, spatialAwarenessFragment, spatialAwarenessFragment.getTag())
                    .commit();

            getSupportFragmentManager().addOnBackStackChangedListener(
                    new FragmentManager.OnBackStackChangedListener() 
                        public void onBackStackChanged() 
                            setTitle("Spatial Awareness");
                        
                    );

请帮帮我

所以我尝试了这个

if (id == R.id.nav_spatial_awareness) 
            setTitle("Spatial Awareness");
            final SpatialAwareness spatialAwarenessFragment = new SpatialAwareness();
            android.support.v4.app.FragmentManager spatialAwarenessManager = getSupportFragmentManager();
            spatialAwarenessManager.beginTransaction()
                    .addToBackStack(null)
                    .replace(R.id.main_content_layout, spatialAwarenessFragment, "spatialAwarenessFragmentTag")
                    .commit();

            getSupportFragmentManager().addOnBackStackChangedListener(
                    new FragmentManager.OnBackStackChangedListener() 
                        public void onBackStackChanged() 
                            android.app.Fragment currentBackStackFragment = getFragmentManager().findFragmentByTag("spatialAwarenessFragmentTag");
                            if(currentBackStackFragment instanceof SpatialAwareness)
                                setTitle("Spatial");
                            
                        
                    );

我给我的片段一个标签,然后尝试匹配实例,然后更改标题,仍然没有好处:(

【问题讨论】:

在您的 backstackchanged 中,您可以检查当前显示的片段,并据此更改工具栏的标题 【参考方案1】:

是的,here 提到的解决方案是将FragmentManager.OnBackStackChangedListener 添加到您的活动的 FragmentManager。

以下是我参与的一个项目的示例: (我有一个包含 7 个 Fragment 的导航抽屉,OverviewFragment 是 MainActivity 打开时打开的第一个)

我的主要活动:

public class MainActivity extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener, FragmentManager.OnBackStackChangedListener 

    ...

    @Override
    protected void onCreate(Bundle savedInstanceState) 

        ...
        NavigationView navigationView = findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);

        if (savedInstanceState == null) 
            // open the default fragment
            OverviewFragment fragment = new OverviewFragment();
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.fragment_container, fragment).commit();
            setTitle(R.string.title_fragment_overview);
        

        getSupportFragmentManager().addOnBackStackChangedListener(this);
    

    @Override
    public boolean onNavigationItemSelected(MenuItem item) 
        // Handle navigation view item clicks here.

        Fragment fragment = null;
        switch (item.getItemId()) 
            case R.id.nav_overview:
                fragment = new OverviewFragment();
                break;
            case R.id.nav_schedule:
                fragment = new ScheduleFragment();
                break;
            case R.id.nav_all_tasks:
                fragment = new AllTasksFragment();
                break;
            case R.id.nav_announcements:
                fragment = new AnnouncementFragment();
                    break;
            case R.id.nav_my_courses:
                fragment = new MyCoursesFragment();
                break;
            case R.id.nav_map:
                fragment = new MapFragment();
                break;
            case R.id.nav_settings:
                fragment = new SettingsFragment();
                break;
            default:
                fragment = new OverviewFragment();
        

        getSupportFragmentManager().beginTransaction()
                .replace(R.id.fragment_container, fragment)
                .addToBackStack(null)
                .commit();

        drawer.closeDrawer(GravityCompat.START);
        return true;
    

    @Override
    public void onBackStackChanged() 
        FragmentManager fragmentManager = getSupportFragmentManager();
        Fragment currentFragment = 
        fragmentManager.findFragmentById(R.id.fragment_container);
        if (currentFragment instanceof  OverviewFragment) 
            setTitle(R.string.title_fragment_overview);
            navigationView.getMenu().findItem(R.id.nav_overview).setChecked(true);
        
        else if (currentFragment instanceof ScheduleFragment) 
            setTitle(R.string.title_fragment_schedule);
            navigationView.getMenu().findItem(R.id.nav_schedule).setChecked(true);
        
        else if (currentFragment instanceof AllTasksFragment) 
            setTitle(R.string.title_fragment_all_tasks);
            navigationView.getMenu().findItem(R.id.nav_all_tasks).setChecked(true);
        
        else if (currentFragment instanceof MyCoursesFragment) 
            setTitle(R.string.title_fragment_my_courses);
            navigationView.getMenu().findItem(R.id.nav_my_courses).setChecked(true);
        
        else if (currentFragment instanceof AnnouncementFragment) 
            setTitle(R.string.title_fragment_announcements);
            navigationView.getMenu().findItem(R.id.nav_announcements).setChecked(true);
        
        else if (currentFragment instanceof MapFragment) 
            setTitle(R.string.title_fragment_map);
            navigationView.getMenu().findItem(R.id.nav_map).setChecked(true);
        
        else if (currentFragment instanceof SettingsFragment) 
            setTitle(R.string.title_fragment_settings);
            navigationView.getMenu().findItem(R.id.nav_settings).setChecked(true);
        
    

这是整个项目:https://github.com/FCI-E-campus/fci-e-campus-android

【讨论】:

以上是关于导航抽屉backstack,如何让actionbar标题在点击后随片段改变的主要内容,如果未能解决你的问题,请参考以下文章

导航组件替换/更改后台堆栈

如何将 android 导航 backstack 弹出到某个片段?

如何获取导航抽屉中的项目以更改视图

如何导航回 Nativescript-vue 中的特定组件或 backstack 条目?

如何在主片段中单击按钮时打开导航抽屉?

如何使用标题 Scroll 使 android 导航抽屉可滚动