[英]Saving Fragment state with Android BottomNavigation
我是 Android 开发的新手,所以我不了解很多,也许是基本的东西,也许甚至陈述的主题也没有完全反映我的问题,我提前道歉,我无法更准确地表述。 请帮我解答一些问题。
我的应用程序中有一个带有三个菜单项的 BottomNavigation。 就像图片上的那样:
最初,我按照标准 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);
}
}
在这段代码中,菜单项切换片段,保存每个片段的state(我不知道具体是多少,它似乎在导航控制器内部的某个地方)。
但是现在我需要中键来执行不同的function,即不参与切换片段。
唯一合适的方法是使用 setOnItemSelectedListener。
然后我的代码将如下所示:
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;
}
});
}
}
它甚至可以工作,只是片段不再保存它们的 state。也就是说,例如,在第一个片段中我有一个 RecyclerView,如果我向下滚动它,切换到另一个片段,然后返回,那么 RecyclerView 就在默认state(not scrolled),也就是state还没有保存。
事实证明,在第一个版本的代码中,我无法单独处理中间菜单项,而在第二个版本中,片段的状态未保存。
提示处理该问题的正确方法。 这样中间的menu item就可以单独分配job了,可以保存state个片段。
您可以使用 navController.addOnDestinationChangedListener 而不是使用 navView.setOnItemClickListener,并且在覆盖的 onDestinationChanged 方法中,您可以检查
if(destination.id == R.id.navigation_update) {
//your custom action here
}
我能够使用导航使用标准工具解决问题。 我刚找到一个菜单项并向其添加了一个 OnClickListener。
BottomNavigationItemView updateBtn = findViewById(R.id.navigation_update);
updateBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// todo
}
});
因此,切换片段和单击中间菜单项都可以正常工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.