Android BottomNavigationView与Fragment重建与重叠问题解决方法探索

简介

在BottomNavigationView+多个Fragment框架下,进行Fragment切换时,会导致Fragment重建,也会出现同级Fragment未hide,导致重叠

解决方法

第一步

初始化一个默认需要显示的Fragment页面

public void InitFragment(Bundle savedInstanceState) {
 //判断activity是否重建,如果不是,则不需要重新建立fragment.
 if (savedInstanceState == null) {
 fragmentManager = getSupportFragmentManager();
 fragmentTransaction = fragmentManager.beginTransaction();
 if (mMovie == null) {
 mMovie = new HomeFragment();
 }
 CurrentFragment = mMovie;
 fragmentTransaction.replace(R.id.nav_host_fragment_activity_main, mMovie).commit();//fragment parent layout id
 }
 }

第二步

监听BottomNavigationView切换事件

binding.navView.setOnNavigationItemSelectedListener(listener);

对同级每一个Fragment进行监听,当进行切换的时候,对其状态进行show或者hide

private BottomNavigationView.OnNavigationItemSelectedListener listener = new BottomNavigationView.OnNavigationItemSelectedListener() {
 @Override
 public boolean onNavigationItemSelected(@NonNull @NotNull MenuItem item) {
 switch (item.getItemId()) {
 case R.id.navigation_home:
 if (mMovie == null) {
 mMovie = new HomeFragment();
 }
 switchContent(CurrentFragment, mMovie);
 return true;
 case R.id.navigation_dashboard:
 if (mExplore == null) {
 mExplore = new ExploreFragment();
 }
 switchContent(CurrentFragment, mExplore);
 return true;
 case R.id.navigation_notifications:
 if (mLibrary == null) {
 mLibrary = new LibraryFragment();
 }
 switchContent(CurrentFragment, mLibrary);
 return true;
 case R.id.navigation_member:
 if (mMember == null) {
 mMember = new MemberFragment();
 }
 switchContent(CurrentFragment, mMember);
 return true;
 }
 return false;
 }
 };

第三步

此为对原Fragment进行隐藏,对要跳转的Fragment进行show,防止页面重叠

public void switchContent(Fragment from, Fragment to) {
 if (from == null || to == null) return;
 if (CurrentFragment != to) {
 CurrentFragment = to;
 fragmentManager = getSupportFragmentManager();
 fragmentTransaction = fragmentManager.beginTransaction();
 if (!to.isAdded()) { 
 //fragment parent layout id
 fragmentTransaction.hide(from).add(R.id.nav_host_fragment_activity_main, to).commit(); 
 } else {
 fragmentTransaction.hide(from).show(to).commit(); 
 }
 }
 }

使用

private FragmentManager fragmentManager;
 private FragmentTransaction fragmentTransaction;
 private HomeFragment mMovie = null;
 private ExploreFragment mExplore = null;
 private LibraryFragment mLibrary = null;
 private MemberFragment mMember = null;
 private Fragment CurrentFragment = null;
InitFragment(savedInstanceState);
 binding.navView.setOnNavigationItemSelectedListener(listener);

同级Fragment跳转

当BottomNavigationView中的同级Fragment需要进行跳转时,可使用EventBus进行跨进程通信实现,然后拿到BottomNavigationView实例进行切换即可,此id为需要跳转的Fragment 页面ID

@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
 public void OnEvent(ChangeFragBean bean) {
 binding.navView.setSelectedItemId(R.id.navigation_dashboard);
 }

Activity跳转到Fragment

同样使用EventBus,从一个Activity跳转到BottomNavigationView的某个Fragment时,需要加一个延迟执行,因为Activity可能未销毁,延迟时间,根据具体手机性能决定,大致在300-500毫秒即可

@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
 public void OnEvent(MermberBean bean) {
 Handler handler = new Handler();
 handler.postDelayed(new Runnable() {
 @Override
 public void run() {
 /**
 *要执行的操作
 */
 binding.navView.setSelectedItemId(R.id.navigation_member);
 }
 }, 250);//3秒后执行Runnable中的run方法
 }
作者:FranzLiszt1847原文地址:https://blog.csdn.net/News53231323/article/details/126015892

%s 个评论

要回复文章请先登录注册