如何打开关闭应用程序后打开的最后一个片段并使用导航抽屉和导航组件重新打开它

Posted

技术标签:

【中文标题】如何打开关闭应用程序后打开的最后一个片段并使用导航抽屉和导航组件重新打开它【英文标题】:How to open the last fragment opened after closed app and reopen it using Navigation drawer and Navigation Component 【发布时间】:2021-11-29 07:46:47 【问题描述】:

更新

由于onSaveInstanceState & onRestoreInstanceState在关闭应用后不能用于存储/恢​​复值,我尝试使用dataStore解决它,但它不起作用,这是我的尝试

DataStoreRepository

@ActivityRetainedScoped
    public static class DataStoreRepository 
        RxDataStore<Preferences> dataStore;

        public static Preferences.Key<Integer> CURRENT_DESTINATION =
                PreferencesKeys.intKey("CURRENT_DESTINATION");

        public final Flowable<Integer> readCurrentDestination;

        @Inject
        public DataStoreRepository(@ApplicationContext Context context) 
            dataStore =
                    new RxPreferenceDataStoreBuilder(Objects.requireNonNull(context), /*name=*/ "settings").build();

            readCurrentDestination = dataStore.data().map(preferences -> 
                if (preferences.get(CURRENT_DESTINATION) != null) 
                    return preferences.get(CURRENT_DESTINATION);
                 else 
                    return R.id.nav_home;
                

            );
        


        public void saveCurrentDestination(String keyName, int value)

            CURRENT_DESTINATION = PreferencesKeys.intKey(keyName);
            dataStore.updateDataAsync(prefsIn -> 
                MutablePreferences mutablePreferences = prefsIn.toMutablePreferences();
                Integer currentKey = prefsIn.get(CURRENT_DESTINATION);

                if (currentKey == null) 
                    saveCurrentDestination(keyName,value);
                

                mutablePreferences.set(CURRENT_DESTINATION,
                        currentKey != null ? value : R.id.nav_home);
                return Single.just(mutablePreferences);
            ).subscribe();

        

    

在 ViewModel 中读取和保存

public final MutableLiveData<Integer> currentDestination = new MutableLiveData<>();


 @Inject
    public PostViewModel(Repository repository, Utils.DataStoreRepository dataStoreRepository) 
        this.repository = repository;
        getAllItemsFromDataBase = repository.localDataSource.getAllItems();
        this.dataStoreRepository = dataStoreRepository;

        dataStoreRepository.readCurrentDestination
                .subscribeOn(Schedulers.io())
                .observeOn(androidSchedulers.mainThread())
                .subscribe(new FlowableSubscriber<Integer>() 
                    @Override
                    public void onSubscribe(@NonNull Subscription s) 
                        s.request(Long.MAX_VALUE);
                    

                    @Override
                    public void onNext(Integer integer) 

                    

                    @Override
                    public void onError(Throwable t) 
                        Log.e(TAG, "onError: " + t.getMessage());
                    

                    @Override
                    public void onComplete() 

                    
                );

    

    public void saveCurrentDestination(int currentDestination) 
        dataStoreRepository
                .saveCurrentDestination("CURRENT_DESTINATION", currentDestination);
    

最后是 MainActivity

@AndroidEntryPoint
public class MainActivity extends AppCompatActivity 

    private static final String TAG = "MainActivity";
    @SuppressWarnings("unused")
    private AppBarConfiguration mAppBarConfiguration;
    private NavHostFragment navHostFragment;
    private  NavController navController;
    NavGraph navGraph;
    private PostViewModel postViewModel;



    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        postViewModel = new ViewModelProvider(this).get(PostViewModel.class);


        setSupportActionBar(binding.appBarMain.toolbar);
        mAppBarConfiguration = new AppBarConfiguration.Builder(R.id.nav_home, R.id.nav_accessory,
                R.id.nav_arcade, R.id.nav_fashion,
                R.id.nav_food, R.id.nav_heath,
                R.id.nav_lifestyle, R.id.nav_sports, R.id.about)
                .setOpenableLayout(binding.drawerLayout)
                .build();


        navHostFragment = (NavHostFragment)
                getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);

        if(navHostFragment !=null) 
          navController = navHostFragment.getNavController();
        

        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(binding.navView, navController);

        navGraph = navController.getNavInflater().inflate(R.navigation.mobile_navigation);

        postViewModel.currentDestination.observe(this,currentDestination -> 
            Log.d(TAG, "currentDestination: " + currentDestination);
            Toast.makeText(this,"currentDestination" + currentDestination,Toast.LENGTH_SHORT).show();
            navGraph.setStartDestination(currentDestination);
            navController.setGraph(navGraph);
        );

        navController.addOnDestinationChangedListener((controller, destination, arguments) -> 
            Log.d(TAG, "addOnDestinationChangedListener: " + destination.getId());
            postViewModel.saveCurrentDestination(destination.getId());
        );



    


    @Override
    public boolean onSupportNavigateUp() 
        return NavigationUI.navigateUp(navController, mAppBarConfiguration)
                || super.onSupportNavigateUp();
    


问题详解

在这个应用程序中,我在导航抽屉中有 9 个菜单项和片段,我想将最后打开的片段保存在 savedInstanceStatedatastore 中,并在用户关闭应用程序并重新打开后再次显示最后打开的片段,但我不知道我会使用哪种方法

Navigation.findNavController(activity,nav_graph).navigate();

binding.navView.setNavigationItemSelectedListener(item -&gt; false);

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_
    android:layout_
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        android:id="@+id/app_bar_main"
        layout="@layout/app_bar_main"
        android:layout_
        android:layout_ />

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_
        android:layout_
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        android:background="@color/color_navigation_list_background"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

</androidx.drawerlayout.widget.DrawerLayout>

activity_main_drawer.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:showIn="navigation_view">

    <group android:checkableBehavior="single">
        <item
            android:id="@+id/nav_home"
            android:title="@string/home"
            android:icon="@drawable/home"
            />

        <item
            android:id="@+id/nav_accessory"
            android:title="@string/accessory"
            android:icon="@drawable/necklace"
            />
        <item
            android:id="@+id/nav_arcade"
            android:title="@string/arcade"
            android:icon="@drawable/arcade_cabinet"
            />
        <item
            android:id="@+id/nav_fashion"
            android:title="@string/fashion"
            android:icon="@drawable/fashion_trend"
            />
        <item
            android:id="@+id/nav_food"
            android:title="@string/food"
            android:icon="@drawable/hamburger"
            />
        <item
            android:id="@+id/nav_heath"
            android:title="@string/heath"
            android:icon="@drawable/clinic"
            />
        <item
            android:id="@+id/nav_lifestyle"
            android:title="@string/lifestyle"
            android:icon="@drawable/yoga"
            />
        <item
            android:id="@+id/nav_sports"
            android:title="@string/sports"
            android:icon="@drawable/soccer"
            />

        <item
            android:id="@+id/nav_favorites"
            android:title="@string/favorites_posts"
            android:icon="@drawable/ic_favorite"
            />

        <item
            android:id="@+id/about"
            android:title="@string/about"
            android:icon="@drawable/about"
            />

    </group>

</menu>

nav_graph.xml

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/mobile_navigation"
    app:startDestination="@id/nav_home">

    <fragment
        android:id="@+id/nav_home"
        android:name="com.blogspot.abtallaldigital.ui.HomeFragment"
        android:label="@string/home"
        tools:layout="@layout/fragment_home">
        <action
            android:id="@+id/action_nav_home_to_detailsFragment"
            app:destination="@id/detailsFragment"
            app:popUpTo="@id/nav_home" />
    </fragment>

    <fragment
        android:id="@+id/nav_accessory"
        android:name="com.blogspot.abtallaldigital.ui.AccessoryFragment"
        android:label="@string/accessory"
        tools:layout="@layout/fragment_accessory" >
        <action
            android:id="@+id/action_nav_Accessory_to_detailsFragment"
            app:destination="@id/detailsFragment" />
    </fragment>

    <fragment
        android:id="@+id/nav_arcade"
        android:name="com.blogspot.abtallaldigital.ui.ArcadeFragment"
        android:label="@string/arcade"
        tools:layout="@layout/fragment_arcade" >
        <action
            android:id="@+id/action_nav_Arcade_to_detailsFragment"
            app:destination="@id/detailsFragment" />
    </fragment>

    <fragment
        android:id="@+id/nav_fashion"
        android:name="com.blogspot.abtallaldigital.ui.FashionFragment"
        android:label="@string/fashion"
        tools:layout="@layout/fragment_fashion" >
        <action
            android:id="@+id/action_nav_Fashion_to_detailsFragment"
            app:destination="@id/detailsFragment" />
    </fragment>
    <fragment
        android:id="@+id/nav_food"
        android:name="com.blogspot.abtallaldigital.ui.FoodFragment"
        android:label="@string/food"
        tools:layout="@layout/food_fragment" >
        <action
            android:id="@+id/action_nav_Food_to_detailsFragment"
            app:destination="@id/detailsFragment" />
    </fragment>
    <fragment
        android:id="@+id/nav_heath"
        android:name="com.blogspot.abtallaldigital.ui.HeathFragment"
        android:label="@string/heath"
        tools:layout="@layout/heath_fragment" >
        <action
            android:id="@+id/action_nav_Heath_to_detailsFragment"
            app:destination="@id/detailsFragment" />
    </fragment>
    <fragment
        android:id="@+id/nav_lifestyle"
        android:name="com.blogspot.abtallaldigital.ui.LifestyleFragment"
        android:label="@string/lifestyle"
        tools:layout="@layout/lifestyle_fragment" >
        <action
            android:id="@+id/action_nav_Lifestyle_to_detailsFragment"
            app:destination="@id/detailsFragment" />
    </fragment>
    <fragment
        android:id="@+id/nav_sports"
        android:name="com.blogspot.abtallaldigital.ui.SportsFragment"
        android:label="@string/sports"
        tools:layout="@layout/sports_fragment" >
        <action
            android:id="@+id/action_nav_Sports_to_detailsFragment"
            app:destination="@id/detailsFragment" />
    </fragment>
    <dialog
        android:id="@+id/about"
        android:name="com.blogspot.abtallaldigital.ui.AboutFragment"
        android:label="about"
        tools:layout="@layout/about" />
    <fragment
        android:id="@+id/detailsFragment"
        android:name="com.blogspot.abtallaldigital.ui.DetailsFragment"
        android:label="Post details"
        tools:layout="@layout/fragment_details" >
        <argument
            android:name="postItem"
            app:argType="com.blogspot.abtallaldigital.pojo.Item" />
    </fragment>
    <fragment
        android:id="@+id/nav_favorites"
        android:name="com.blogspot.abtallaldigital.ui.FavoritesFragment"
        android:label="Favorites posts"
        tools:layout="@layout/fragment_favorites" >
        <action
            android:id="@+id/action_favoritesFragment_to_detailsFragment"
            app:destination="@id/detailsFragment" />
    </fragment>
</navigation>

MainActivity 类

@AndroidEntryPoint
public class MainActivity extends AppCompatActivity 

    @SuppressWarnings("unused")
    private AppBarConfiguration mAppBarConfiguration;
    public static Utils.DataStoreRepository DATA_STORE_REPOSITORY;


    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());


        setSupportActionBar(binding.appBarMain.toolbar);
        mAppBarConfiguration = new AppBarConfiguration.Builder(R.id.nav_home, R.id.nav_accessory,
                R.id.nav_arcade, R.id.nav_fashion,
                R.id.nav_food, R.id.nav_heath,
                R.id.nav_lifestyle, R.id.nav_sports, R.id.about)
                .setOpenableLayout(binding.drawerLayout)
                .build();


        NavHostFragment navHostFragment = (NavHostFragment)
                getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);

        assert navHostFragment != null;
        NavController navController = navHostFragment.getNavController();

        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(binding.navView, navController);


    


    @Override
    public boolean onSupportNavigateUp() 
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.navigateUp(navController, mAppBarConfiguration)
                || super.onSupportNavigateUp();
    


【问题讨论】:

你read the documentation了吗?它以这种情况为例。 @ianhanniballake 谢谢我现在已经阅读了,我会继续寻找是否有其他方法可以做到这一点,而不是切换navGraph.startDestination 【参考方案1】:

免责声明:

由于SharedPreference 迟早会被弃用,下面有一个使用DataStore 的更新。


使用SharedPreference

在应用关闭/关闭后,onSaveInstanceState & onRestoreInstanceState 不能用于存储/恢​​复值。

即使应用没有关闭,你也不能依赖它们来存储大型对象或长时间存储对象。

您可以使用SharedPreference 来存储一个值,该值映射到应用程序存在之前的最后一个打开片段。

这里我存储了一些任意值,因为建议不要存储应用程序 ID,因为它们可能因应用程序启动而异。因此,您可以存储任意值并将它们映射到当前应用启动时生成的 ID。

我选择这些值作为数组索引:

// Array of fragments
private Integer[] fragments = 
    R.id.nav_home, 
    R.id.nav_accessory,
    R.id.nav_arcade, 
    R.id.nav_fashion,
    R.id.nav_food, 
    R.id.nav_heath,
    R.id.nav_lifestyle, 
    R.id.nav_sports, 
    R.id.about
;

然后每次启动应用程序;即在onCreate() 方法中,您可以从SharedPreference 中选择当前索引,然后调用graph.setStartDestination()

// Getting the last fragment:
SharedPreferences mSharedPrefs = getSharedPreferences("SHARED_PREFS", MODE_PRIVATE);
int fragIndex = mSharedPrefs.getInt(LAST_FRAGMENT, -1); // The last fragment index 
// Check if it's a valid index
if (fragIndex >= 0 && fragIndex < fragments.length) 
    // Navigate to this fragment
    int currentFragment = fragments[fragIndex];
    graph.setStartDestination(currentFragment);

    // Change the current navGraph
    navController.setGraph(graph);
 

您可以使用navControllerOnDestinationChangedListener 更改目标后向sharedPreference 注册新值:

// Listener to the change in fragments, so that we can updated the shared preference
navController.addOnDestinationChangedListener((controller, destination, arguments) -> 
    int fragmentIndex = Arrays.asList(fragments).indexOf(destination.getId());
    SharedPreferences.Editor editor = mSharedPrefs.edit();
    editor.putInt(LAST_FRAGMENT, fragmentIndex).apply();
);

将其集成到您的代码中:

@AndroidEntryPoint
public class MainActivity extends AppCompatActivity 

    private static final String TAG = "MainActivity";
    @SuppressWarnings("unused")
    private AppBarConfiguration mAppBarConfiguration;
    private NavHostFragment navHostFragment;
    private  NavController navController;
    NavGraph navGraph;

    
    // Array of fragments
    private Integer[] fragments = 
        R.id.nav_home, 
        R.id.nav_accessory,
        R.id.nav_arcade, 
        R.id.nav_fashion,
        R.id.nav_food, 
        R.id.nav_heath,
        R.id.nav_lifestyle, 
        R.id.nav_sports, 
        R.id.about
    ;
    
    // Key for saving the last fragment in the Shared Preferences
    private static final String LAST_FRAGMENT = "LAST_FRAGMENT";
    
    
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());


        setSupportActionBar(binding.appBarMain.toolbar);
        mAppBarConfiguration = new AppBarConfiguration.Builder(R.id.nav_home, R.id.nav_accessory,
                R.id.nav_arcade, R.id.nav_fashion,
                R.id.nav_food, R.id.nav_heath,
                R.id.nav_lifestyle, R.id.nav_sports, R.id.about)
                .setOpenableLayout(binding.drawerLayout)
                .build();


        navHostFragment = (NavHostFragment)
                getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);

        if(navHostFragment !=null) 
          navController = navHostFragment.getNavController();
        

        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(binding.navView, navController);

        navGraph = navController.getNavInflater().inflate(R.navigation.mobile_navigation);

        
        // Getting the last fragment:
        SharedPreferences mSharedPrefs = getSharedPreferences("SHARED_PREFS", MODE_PRIVATE);
        int fragIndex = mSharedPrefs.getInt(LAST_FRAGMENT, -1); // The last fragment index 
        // Check if it's a valid index
        if (fragIndex >= 0 && fragIndex < fragments.length) 
            // Navigate to this fragment
            int currentFragment = fragments[fragIndex];
            graph.setStartDestination(currentFragment);

            // Change the current navGraph
            navController.setGraph(graph);
         
        

        
        // Listener to the change in fragments, so that we can updated the shared preference
        navController.addOnDestinationChangedListener((controller, destination, arguments) -> 
            int fragmentIndex = Arrays.asList(fragments).indexOf(destination.getId());
            SharedPreferences.Editor editor = mSharedPrefs.edit();
            editor.putInt(LAST_FRAGMENT, fragmentIndex).apply();
        );
        

    


    @Override
    public boolean onSupportNavigateUp() 
        return NavigationUI.navigateUp(navController, mAppBarConfiguration)
                || super.onSupportNavigateUp();
    



使用数据存储

自从我在这个项目中从 sharedpreferences 迁移到 dataStore 后,我尝试了与您的解决方案相同的操作,但它不起作用,我将发布我的尝试,您可以查看它以查看问题所在,然后您可以使用 dataStore soultion 编辑您的答案

所以,我将使用相同的方法,但使用 DataStore(相同的片段数组,存储索引而不是片段目标 ID)。

因此,您需要添加片段 ID 数组,以便在 DataStore 进程中读取它:

// Array of fragment IDs
private Integer[] fragments = 
    R.id.nav_home, 
    R.id.nav_accessory,
    R.id.nav_arcade, 
    R.id.nav_fashion,
    R.id.nav_food, 
    R.id.nav_heath,
    R.id.nav_lifestyle, 
    R.id.nav_sports, 
    R.id.about
;

然后在存储库中更改逻辑以使用索引而不是片段 ID:

@Inject
public DataStoreRepository(@ApplicationContext Context context) 
    dataStore =
            new RxPreferenceDataStoreBuilder(Objects.requireNonNull(context), /*name=*/ "settings").build();
        
    readCurrentDestination =
        dataStore.data().map(preferences -> 

            Integer fragIndex = preferences.get(CURRENT_DESTINATION);
            if (fragIndex == null) fragIndex = 0;

            if (fragIndex >= 0 && fragIndex <= fragments.length) 
                // Navigate to the fragIndex
                return fragments[fragIndex];
             else 
                return R.id.nav_home;
            
        ); 
    
   

ViewModel 中,您不应该为Flowable 订阅永久的 Observable,因为这将永久提交对观察到的数据的任何更改,但是您可以将Flowable 转换为Single,以便您只能在应用程序启动时获得片段 ID 的单个(第一个)值,并且不再注册观察者。 Check Documentation 了解更多详情。

在你的 ViewModel 中应用它:

@Inject
public PostViewModel(Repository repository, Utils.DataStoreRepository dataStoreRepository) 
    this.repository = repository;
    getAllItemsFromDataBase = repository.localDataSource.getAllItems();
    this.dataStoreRepository = dataStoreRepository;

    dataStoreRepository.readCurrentDestination.firstOrError().subscribeWith(new DisposableSingleObserver<Integer>() 

        @Override
        public void onSuccess(@NotNull Integer destination) 
        
            // Must be run at UI/Main Thread
            runOnUiThread(() -> 
                currentDestination.setValue(destination);
            );
            
        

        @Override
        public void onError(@NotNull Throwable error) 
            error.printStackTrace();
        
    ).dispose();


然后当您观察活动中的currentDestination MutableLiveData 时:更改那里的当前目的地(您已经做得很好):

postViewModel.currentDestination.observe(this,currentDestination -> 
    Log.d(TAG, "currentDestination: " + currentDestination);
    Toast.makeText(this,"currentDestination" + currentDestination,Toast.LENGTH_SHORT).show();
    navGraph.setStartDestination(currentDestination);
    navController.setGraph(navGraph);
);

每当目标更改时,将当前片段保存到DataStore

ViewModel

public void saveCurrentDestination(int value)
    int fragmentIndex = Arrays.asList(fragments).indexOf(value);
    CURRENT_DESTINATION = PreferencesKeys.intKey(keyName);
    dataStore.updateDataAsync(prefsIn -> 
        MutablePreferences mutablePreferences = prefsIn.toMutablePreferences();
        mutablePreferences.set(CURRENT_DESTINATION, fragmentIndex);
        return Single.just(mutablePreferences);
    ).subscribe();


【讨论】:

自从我在这个项目中从 sharedpreferences 迁移到 dataStore 后,我尝试与您的解决方案相同,但它不起作用,我将发布我的尝试,您可以查看它以查看是什么错了,那么您可以使用 dataStore soultion 编辑您的答案,我将不胜感激 @DrMido 太好了.. 我没有注意到您正在使用 DataStore;我刚刚更新了答案。希望它符合您的需要 我确实像你一样乱扔垃圾,但不幸的是它不起作用,当应用程序启动时,我收到一条日志和 toast 消息,其编号为 currentDestination currentDestination: 2131296601 这是家庭 id ,它永远不会改变,它看起来 navController.addOnDestinationChangedListener 没有被调用,我也尝试了 navView.setNavigationItemSelectedListener 并获取项目 id 并将其存储到 currentDestination mutablelivedata 和同样的问题,缺少一些东西 @DrMido 我看到我错过了更新当前目标部分;请看答案UPDATE 2部分 很高兴听到这个消息! @DrMido 对于第一点。片段 ID 由应用程序生成;并且建议不要在不同的应用程序启动时使用它们,因为它们可能因应用程序启动而异。因此,您可以存储一个不会在下次应用启动时映射到片段 ID 的值,因此它将转到默认片段(主页)。【参考方案2】:

如何在导航图中存储当前位置并不重要(我们实际上是在讨论存储单个 long 值以及最终的一些参数值)。

前提条件本身应该已经解释了它是如何工作的:

能够使用global NavAction 导航到每个目的地。 能够将存储的目标 ID 解析为 global NavAction。 不要忘记导航参数(例如itemId)。

与此类似,可能会丢失回栈条目,但可以直接导航。如果这还不够,请存储 NavController 返回堆栈条目,然后播放它们(不建议)。

【讨论】:

为什么要保存动作本身以及为什么要存储动作本身,这可以很简单,只需在每次应用启动时使用navGraph.startDestination,导航项 id destination.getId() 的 int 不长

以上是关于如何打开关闭应用程序后打开的最后一个片段并使用导航抽屉和导航组件重新打开它的主要内容,如果未能解决你的问题,请参考以下文章

底部导航图标不变

如何使用导航抽屉打开和关闭更改按钮图像

第一个片段替换为第二个片段后,如何打开导航抽屉

从另一个活动返回后如何恢复活动中最后打开的片段

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

如何使向上按钮返回而不是打开导航抽屉