我的应用程序使用bottomnavigationbar在片段之间切换,它是这样做的:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView bottomNav = findViewById(R.id.barra);
bottomNav.setOnNavigationItemSelectedListener(navListener);
getSupportFragmentManager().beginTransaction().replace(R.id.container, new KeyboardFragment()).commit();
bottomNav.setSelectedItemId(R.id.keyboard);
}
private BottomNavigationView.OnNavigationItemSelectedListener navListener =
new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()){
case R.id.camera:
selectedFragment = new CameraFragment();
break;
case R.id.keyboard:
selectedFragment = new KeyboardFragment();
break;
case R.id.settings:
selectedFragment = new SettingsFragment();
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.container,
selectedFragment).commit();
return true;
}
};
}
我想要那些 Fragments
是静态的,所以当我在它们之间切换时,它们的内容和视图不会消失。我试着在里面创造它们 MainActivity
的 onCreate()
方法,但它只帮助在内部保留文本 EditText
小部件,其余的视图和内容都消失了。
我也见过其他类似的问题,但回答得很差,我对这一点还不熟悉。在回答了一些类似的问题之后,我尝试使用如下函数 add()
或者 attach()
而不是 replace()
但我不认为我做得很好;事实上,有时我的应用程序会崩溃。
我应该把layout.xml文件也粘贴到这里吗?片段被“显示”成一个简单的 FrameLayout
. 事先谢谢:)
2条答案
按热度按时间vbkedwbf1#
replace()
意味着销毁这个,并在其位置添加新的,因为你的代码是现在你不能使用add()
或者是因为根据这个switch case,您将在每次导航时创建一个新的片段示例。它会浪费内存,最终应用程序会崩溃OutOfMemoryException
你能做什么?不幸的是,使用底部导航没有太多的选项,但是您可以使用以下选项进行改进
1使用
viewmodels
为每个碎片和附加所有viewmodels
通过这样的主机活动,您不必每次创建片段时都加载数据,数据将保留在viewmodels中2或使用viewpager保存片段viewpager将能够在内存中保存所有片段并查看所需片段,通过调用
setCurrentItem()
在viewpager上OnNavigationItemSelected()
3使用add()
而不是replace()
并使您的片段是单例的,这样您就不会每次都加载数据(如果您不使用视图模型),现在还可以跟踪最后一个片段,如果用户转到另一个片段,并且在转到其他任何地方之前返回到这个片段,您只需使用getSupportFragmantManager().popBackStack()
若要移除此片段堆栈,请弹出后堆栈并添加另一个片段4使用其他形式的导航—请参阅导航组件,让您的生活更轻松
也许有更好的解决方案,但这是我所能想到的根据我的经验,这不是很多,虽然导航组件也做替换的事情,我不认为这是很坏的,如果你使用视图模型来保存数据。
快乐编码
m2xkgtsf2#
这就是我成功解决问题的方法:
首先,所有片段都声明为内部的字段
MainActivity
类以及变量selected
,稍后将使用:然后,在类内部也定义了以下方法,其中
R.id.container
是framelayout或用于显示膨胀碎片的任何视图:最后,任何菜单的侦听器都是这样定义的
MainActivity
的OnCreate()
方法:通过这种方式,菜单只是在视觉上隐藏和显示片段,它们只声明一次,直到应用程序关闭才被销毁,因此只要应用程序运行,它们的所有字段和视图都会保存在内存中。