• 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
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    第二步

    监听BottomNavigationView切换事件

     binding.navView.setOnNavigationItemSelectedListener(listener);
    
    • 1

    对同级每一个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;
            }
        };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    第三步

    此为对原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(); 
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    使用

        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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
      InitFragment(savedInstanceState);
     binding.navView.setOnNavigationItemSelectedListener(listener);
    
    • 1
    • 2

    同级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);
        }
    
    • 1
    • 2
    • 3
    • 4

    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方法
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    两阶段鲁棒优化matlab实现——C&CG和benders
    mysql内部存储代码的优势
    【24届数字IC秋招总结】正式批面试经验汇总9——飞腾
    SpringBoot 时 jar 报错 没有主清单属性
    解决spawn-fcgi:child exited with: 127/126/1报错
    HSCTF2022-re题解
    【PyTorch】深度学习实践之CNN高级篇——实现复杂网络
    在哪些场景下不建议自增数据库主键
    点餐小程序实战教程05-用户注册
    java基础
  • 原文地址:https://blog.csdn.net/News53231323/article/details/126015892