简体   繁体   English

使用 Android BottomNavigation 保存片段 state

[英]Saving Fragment state with Android BottomNavigation

I'm new to Android development, so I do not understand many, perhaps elementary things, perhaps even the stated topic does not fully reflect my questions, I apologize in advance, I could not formulate more precisely.我是 Android 开发的新手,所以我不了解很多,也许是基本的东西,也许甚至陈述的主题也没有完全反映我的问题,我提前道歉,我无法更准确地表述。 Please help me with some questions.请帮我解答一些问题。

I have a BottomNavigation in my application with three menu items.我的应用程序中有一个带有三个菜单项的 BottomNavigation。 Like on a picture:就像图片上的那样:

bottom nav底部导航

Initially, I did it as in the standard Android Studio example:最初,我按照标准 Android Studio 示例进行操作:

public class MainActivity extends AppCompatActivity {

    private ActivityMainBinding binding;
    private NavController navController;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        BottomNavigationView navView = findViewById(R.id.nav_view);
        AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
                R.id.navigation_home, R.id.navigation_update, R.id.navigation_notifications)
                .build();

        navController = Navigation.findNavController(this, R.id.nav_host_fragment_activity_main);

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

In this code, the menu items switch fragments, saving the state of each of them (I don't know how exactly, it seems to be somewhere inside the navigation controller).在这段代码中,菜单项切换片段,保存每个片段的state(我不知道具体是多少,它似乎在导航控制器内部的某个地方)。

But now I needed the middle button to perform a different function, ie not to participate in switching fragments.但是现在我需要中键来执行不同的function,即不参与切换片段。

The only adequate way to do this is to use setOnItemSelectedListener.唯一合适的方法是使用 setOnItemSelectedListener。

Then my code will look like this:然后我的代码将如下所示:

public class MainActivity extends AppCompatActivity {

    private ActivityMainBinding binding;
    private NavController navController;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        BottomNavigationView navView = findViewById(R.id.nav_view);
        AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
                R.id.navigation_home, R.id.navigation_update, R.id.navigation_notifications)
                .build();

        navController = Navigation.findNavController(this, R.id.nav_host_fragment_activity_main);

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

        navView.setOnItemSelectedListener(
                new NavigationBarView.OnItemSelectedListener() {
                    @Override
                    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                        switch (item.getItemId()) {

                            case R.id.navigation_home:
                                navController.navigate(R.id.navigation_home);
                                break;
                            case R.id.navigation_update:
                                // work for middle menu item
                                break;
                            case R.id.navigation_notifications:
                                navController.navigate(R.id.navigation_notifications, savedInstanceState);
                                break;
                        }
                        return true;
                    }
                });
    }
}

It even works, except that the fragments no longer save their state. That is, for example, in the first fragment I have a RecyclerView, if I scroll it down, switch to another fragment, and then return back, then the RecyclerView is in the default state (not scrolled), that is the state has not been saved.它甚至可以工作,只是片段不再保存它们的 state。也就是说,例如,在第一个片段中我有一个 RecyclerView,如果我向下滚动它,切换到另一个片段,然后返回,那么 RecyclerView 就在默认state(not scrolled),也就是state还没有保存。

It turns out that in the first version of the code I can't do individual work with the middle menu item, and in the second version the states of the fragments are not saved.事实证明,在第一个版本的代码中,我无法单独处理中间菜单项,而在第二个版本中,片段的状态未保存。

Prompt correct way to deal with this problem.提示处理该问题的正确方法。 So that the middle menu item can be assigned a separate job, and the state of the fragments can be saved.这样中间的menu item就可以单独分配job了,可以保存state个片段。

instead of using navView.setOnItemClickListener, you can use navController.addOnDestinationChangedListener, and in overrided onDestinationChanged method, you can check您可以使用 navController.addOnDestinationChangedListener 而不是使用 navView.setOnItemClickListener,并且在覆盖的 onDestinationChanged 方法中,您可以检查

if(destination.id ==  R.id.navigation_update) {
    //your custom action here
}

I was able to solve the problem with standard tools using Navigation.我能够使用导航使用标准工具解决问题。 I just found a menu item and added a OnClickListener to it.我刚找到一个菜单项并向其添加了一个 OnClickListener。

BottomNavigationItemView updateBtn = findViewById(R.id.navigation_update);
updateBtn.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View view) {
       // todo
   }
});  

Thus, both switching fragments and clicking on the middle menu item work correctly.因此,切换片段和单击中间菜单项都可以正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM