[英]save fragment state in a bottom navigation bar
I have an activity, which basically is a navigation bottom bar containing fragments.我有一个活动,它基本上是一个包含片段的导航底部栏。 If the the user is logged in, the bottom navigation shows 4 fragments: market, favorite, upload and profile.
如果用户已登录,底部导航显示 4 个片段:市场、收藏夹、上传和个人资料。 If the user is a guest, there are two fragments: market and login.
如果用户是访客,则有两个片段:市场和登录。
Before, every time someone swapped from a fragment to another, it was generated again.以前,每次有人从一个片段交换到另一个片段时,它都会再次生成。 However, I wanted to conserve the state of the fragment, so if someone applied a filter in the market and came back, it had to keep the filter applied.
但是,我想保留片段的 state,所以如果有人在市场上应用了过滤器并回来,它必须保持过滤器应用。 I tried implementing this solution https://medium.com/@oluwabukunmi.aluko/bottom-navigation-view-with-fragments-a074bfd08711 but I feel is not the best so far.
我尝试实施此解决方案https://medium.com/@oluwabukunmi.aluko/bottom-navigation-view-with-fragments-a074bfd08711但我觉得到目前为止还不是最好的。
The code of the nav activity is:导航活动的代码是:
public class NavigationActivity extends AppCompatActivity {
final Fragment market= new MarketFragment();
final Fragment favorite = new FavoriteFragment();
final Fragment updateProduct = new AddProductFragment();
final Fragment userProfile = new UserProfileFragment();
final Fragment loginregister = new LoginOrRegisterFragment();
final FragmentManager fm = getSupportFragmentManager();
Fragment active = market;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(UnipopApp.usuariLoggejat.getUserLogged() != null){
setContentView(R.layout.main);
}
else{
setContentView(R.layout.main_guest);
}
setUpNavigation();
}
public void setUpNavigation() {
BottomNavigationView bottomNavigationView;
if(UnipopApp.usuariLoggejat.getUserLogged() != null) {
bottomNavigationView = findViewById(R.id.bottom_navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(mOnNavegationItemSelectedListener);
fm.beginTransaction().add(R.id.nav_host_fragment, favorite, "2").hide(favorite).commit();
fm.beginTransaction().add(R.id.nav_host_fragment, updateProduct, "3").hide(updateProduct).commit();
fm.beginTransaction().add(R.id.nav_host_fragment, userProfile, "5").hide(userProfile).commit();
fm.beginTransaction().add(R.id.nav_host_fragment, market, "1").commit();
}
else {
bottomNavigationView = findViewById(R.id.bottom_navigation_guest);
bottomNavigationView.setOnNavigationItemSelectedListener(mOnNavegationItemSelectedListener);
fm.beginTransaction().add(R.id.nav_host_fragment_guest, loginregister, "6").hide(loginregister).commit();
fm.beginTransaction().add(R.id.nav_host_fragment_guest, market, "1").commit();
}
}
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavegationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.action_home:
fm.beginTransaction().hide(active).show(market).commit();
active = market;
return true;
case R.id.action_favorites:
fm.beginTransaction().hide(active).show(favorite).commit();
active = favorite;
return true;
case R.id.addProduct_fragment:
fm.beginTransaction().hide(active).show(updateProduct).commit();
active = updateProduct;
return true;
case R.id.action_user_profile:
fm.beginTransaction().hide(active).show(userProfile).commit();
active = userProfile;
return true;
case R.id.action_user_profile_guest:
fm.beginTransaction().hide(active).show(loginregister).commit();
active = loginregister;
return true;
}
return false;
}
};
}
It works but I had to delete the nav graph... However, the thing is that when someone marks a product as favorite in the market and moves to the favorite fragment, it does not appear.它有效,但我不得不删除导航图......但是,问题是当有人将产品标记为市场上的最爱并移动到最喜欢的片段时,它不会出现。 Obviously, it just shows up the fragment again, it does not generate it back with the call from the server.
显然,它只是再次显示片段,它不会通过来自服务器的调用生成它。
I am looking for other options because I don't like this solution.我正在寻找其他选择,因为我不喜欢这个解决方案。 If someone can lend me a hand, it would be great.
如果有人可以帮我一把,那就太好了。
Thanks谢谢
Recommended solution using Bottom Navigation View and Fragment Navigation.使用底部导航视图和片段导航的推荐解决方案。 Use Activity's SharedViewModel to persist the states of all the navigation fragments.
使用Activity 的 SharedViewModel来持久化所有导航片段的状态。
Layout XML (rees/layout/activity_main.xml)布局 XML (rees/layout/activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:labelVisibilityMode="labeled"
app:menu="@menu/bottom_navigation_menu" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@id/bottom_navigation"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/core_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
Navigation XML (res/navigation/core_navigation.xml)导航 XML (res/navigation/core_navigation.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"
app:startDestination="@+id/navigation_feed">
<fragment
android:id="@+id/navigation_home"
android:name="com.example.HomeFragment"
android:label="@string/home_title"
tools:layout="@layout/home_fragment" />
<fragment
android:id="@+id/navigation_favorites"
android:name="com.example.FavoritesFragment"
android:label="@string/favorites_title"
tools:layout="@layout/favorites_fragment" />
<!--Fill this with other fragments like above-->
</navigation>
Menu XML (res/menu/bottom_navigation_menu.xml)菜单 XML (res/menu/bottom_navigation_menu.xml)
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/navigation_home"
android:enabled="true"
android:icon="@drawable/ic_home"
android:title="@string/home_title"/>
<item
android:id="@+id/navigation_favorites"
android:enabled="true"
android:icon="@drawable/ic_favorites"
android:title="@string/favorites_title"/>
<!--Fill this with other fragments like above-->
</menu>
Activity活动
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setupNavigation()
}
private fun setupNavigation() {
val navController = (supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment).navController
binding.bottomNavigation.setupWithNavController(navController)
}
}
You can save filter selection in fragment's viewmodel.您可以将过滤器选择保存在片段的视图模型中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.