1. 关于Android studio新建的Bottom Navigation Activity

2. 解决思路

3. 具体操作

4. 关于androidstudio自生成的xml文件的代码修改


1. 关于Android studio新建的Bottom Navigation Activity

AndroidStudio自带的生成的Navigation控制fragment的转换是直接使用的replace()方法,这会使每次点击底部的按钮都会重新实例化一个fragment,无论是跳转到其它fragment还是点击当前fragment对应的按钮。

而要使fragment不被回收并重新实例化,需要使用hide()和show()方法,具体实现下文。

2. 解决思路

首先在MainActivity实例化fragment,将所有fragment包含在list中。方便使用FragmentTransaction来实现对fragment的操作

        private val home = HomeFragment()private val dash = DashboardFragment()private val notification = NotificationsFragment()val list = arrayListOf(home, dash, notification)

构建一个FragmentTransaction来实现操作,以及两个Int变量获取当前fragment和要跳转的目的fragment

        private lateinit var transaction: FragmentTransactionvar mFragment = 0var toFragment = 0

这样就能实现对fragment的精准操控,这些定义都是全局变量

3. 具体操作

1. 首先是第一次打开的初始化,显示homefragment,即打开的默认的fragment

    private fun init(){transaction = supportFragmentManager.beginTransaction()transaction.add(R.id.nav_host_fragment_activity_main, home).show(home).commit()}

R.id.nav_host_fragment_activity_main是activity_main中fragment控件的id,这是androidstudio生成时默认的。

2. 其次是转换fragment的实现函数通过两个简单的if语句实现不同的hide和show函数

    private fun switchFragment(transaction: FragmentTransaction){val from = list[mFragment]val to = list[toFragment]if (mFragment == toFragment) returnif (from.isAdded) {if (to.isAdded) {transaction.hide(from).show(to).commit()} else {transaction.add(R.id.nav_host_fragment_activity_main, to).hide(from).show(to).commit()}} else {if (to.isAdded) {transaction.add(R.id.nav_host_fragment_activity_main, from).hide(from).show(to).commit()} else {transaction.add(R.id.nav_host_fragment_activity_main, from).add(R.id.nav_host_fragment_activity_main, to).hide(from).show(to).commit()}}}

具体逻辑自己理解

3. 最后是菜单按钮的点击事件

    private fun click(){binding.navView.setOnItemSelectedListener{transaction = supportFragmentManager.beginTransaction()when(it.itemId) {R.id.navigation_home -> {toFragment = 0switchFragment(transaction)mFragment = 0}R.id.navigation_dashboard -> {toFragment = 1switchFragment(transaction)mFragment = 1}R.id.navigation_notifications -> {toFragment = 2switchFragment(transaction)mFragment = 2}}true}}

每次跳转前给toFragment赋值,跳转后给mFragment赋值,这样switch函数就能知道当前的fragment和目的fragment。

4. 关于androidstudio自生成的xml文件的代码修改

activity_main.xml文件中fragment标签,取消使用navigation绑定几个fragment,去掉最后一个属性即可

<fragmentandroid:id="@+id/nav_host_fragment_activity_main"android:name="androidx.navigation.fragment.NavHostFragment"android:layout_width="match_parent"android:layout_height="match_parent"app:defaultNavHost="true"app:layout_constraintBottom_toTopOf="@id/nav_view"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent"app:navGraph="@navigation/mobile_navigation" 这一行删掉
/>

这样的话,res文件夹中的navigation文件夹就可以直接删除

贴一个MainActivity的全部代码吧

package com.example.testfragmentimport android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentTransaction
import com.example.testfragment.databinding.ActivityMainBinding
import com.example.testfragment.ui.DashboardFragment
import com.example.testfragment.ui.HomeFragment
import com.example.testfragment.ui.NotificationsFragmentclass MainActivity : AppCompatActivity() {companion object{private val home = HomeFragment()private val dash = DashboardFragment()private val notification = NotificationsFragment()val list = arrayListOf(home, dash, notification)private lateinit var transaction: FragmentTransactionvar mFragment = 0var toFragment = 0}private lateinit var binding: ActivityMainBindingoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)binding = ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)init()click()}private fun init(){transaction = supportFragmentManager.beginTransaction()transaction.add(R.id.nav_host_fragment_activity_main, home).show(home).commit()}private fun click(){binding.navView.setOnItemSelectedListener{transaction = supportFragmentManager.beginTransaction()when(it.itemId) {R.id.navigation_home -> {toFragment = 0switchFragment(transaction)mFragment = 0}R.id.navigation_dashboard -> {toFragment = 1switchFragment(transaction)mFragment = 1}R.id.navigation_notifications -> {toFragment = 2switchFragment(transaction)mFragment = 2}}true}}private fun switchFragment(transaction: FragmentTransaction){val from = list[mFragment]val to = list[toFragment]if (mFragment == toFragment) returnif (from.isAdded) {if (to.isAdded) {transaction.hide(from).show(to).commit()} else {transaction.add(R.id.nav_host_fragment_activity_main, to).hide(from).show(to).commit()}} else {if (to.isAdded) {transaction.add(R.id.nav_host_fragment_activity_main, from).hide(from).show(to).commit()} else {transaction.add(R.id.nav_host_fragment_activity_main, from).add(R.id.nav_host_fragment_activity_main, to).hide(from).show(to).commit()}}}
}

欢迎评论批评指正

Android解决fragment来回切换重新实例化问题相关推荐

  1. [Android]解决Fragment无法使用android:onClick属性

     有过MFC或者WinForm或者WPF经验的程序员一定对于Button的Click事件绑定情有独钟,然而当转移到 Android平台开发的时候会发现,之前的种种便利全都不在,只有看着闹心的set ...

  2. android fragment实例化,Android使得Fragment 切换时不重新实例化

    以前实现Fragment的切换都是用replace方法实现 public void startFragmentAdd(Fragment fragment) { FragmentManager frag ...

  3. Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信...

    以下内容为原创,转载请注明:http://www.cnblogs.com/tiantianbyconan/p/3360938.html 如新浪微博下面的标签切换功能,我以前也写过一篇博文(http:/ ...

  4. Android 关于fragment切换重新加载的解决分享给大家

    在项目中需要进行Fragment的切换,一直都是用replace()方法来替换Fragment 但是,这样会有一个问题 ,应该很多朋友都遇到过: 每次切换的时候,Fragment都会重新实例化,也就是 ...

  5. android viewpager fragment传值,Android开发中如何解决Fragment +Viewpager滑动页面重复加载的问题...

    前言 之前在做一个Viewpager上面加载多个Fragment时总会实例化已经创建好的Fragmnet对象类似 viewPager.setAdapter(new FragmentPagerAdapt ...

  6. android 为什么fragment在调用hide方法后没有生效_Android 多 Fragment 切换优化

    code小生,一个专注 Android 领域的技术平台 公众号回复 Android 加入我的安卓技术群 作者:DDDong丶 链接:https://www.jianshu.com/p/c8e8a024 ...

  7. Android studio实现底部导航,AndroidStudio制作底部导航栏以及用Fragment实现切换功能...

    前言 大家好,我是 Vic,今天给大家带来AndroidStudio制作底部导航栏以及用Fragment实现切换功能的概述,希望你们喜欢 学习目标 AndroidStudio制作底部导航栏以及用Fra ...

  8. Android解决程序切换后台被干掉,恢复状态问题

    Android解决程序切换后台被干掉,恢复状态问题 参考文章: (1)Android解决程序切换后台被干掉,恢复状态问题 (2)https://www.cnblogs.com/caiwan/p/And ...

  9. Android 在Fragment中执行onActivityResult不被调用的简单解决方法

    Android 在Fragment中执行onActivityResult不被调用的简单解决方法 参考文章: (1)Android 在Fragment中执行onActivityResult不被调用的简单 ...

最新文章

  1. Java中的匿名对象
  2. Effective Java 之个人总结
  3. 百度网盘文件分享演示,如何查看已经分享的文件
  4. 相似三角形_JAVA
  5. 在 C/C++ 中使用 TensorFlow 预训练好的模型—— 直接调用 C++ 接口实现
  6. copy与mutableCopy的区别总结
  7. 计算机专业需要学好的数学知识,学好数学对计算机专业重要吗?
  8. 如何为企业量身打造一套高可用系统?
  9. 特斯拉2020全年交付49.955万辆车,未能完成50万辆目标
  10. 模板类的析构函数如何写_项目经理如何正确写好年终总结+10大PPT模板可直接套用...
  11. GO语言学习之路26
  12. 计算机考试spss数据分析,基于SPSS的数据分析
  13. windows下支持H265的rtmp ffplay播放器 ffmpeg的编译
  14. Spring Boot 2020 官方基础68课程第十六个 Securing a Web Application
  15. lol刷金币python脚本_用Python写王者荣耀刷金币脚本
  16. python中eval什么意思_python中eval函数作用
  17. 俞敏洪:人生最重要的两件事是什么?
  18. 习题2.7 编写程序,输出0到360中所有度数为5°倍数的角度的正弦值和余弦值
  19. Python3.6中对爬取网页中的/XBB的处理
  20. android手机Down版本

热门文章

  1. 2022一建四色笔记
  2. 设置计算机关机时间快捷键,怎么让电脑定时关机设置大全
  3. 寻一款带有记事本+闹钟的桌面便签小软
  4. C#2.0 编写window服务
  5. vrf中的ipsec
  6. Unity-UGUI制作的小地图-可放大缩小视角,大地图小地图切换
  7. 一周技术学习笔记(第67期)-CPU的设计跟开闭原则有关系吗
  8. 5000词学英语——DAY6
  9. 获取汉字偏旁部首 Python版本
  10. springboot整合dubbo的问题之一。zookeeper客户端和zookeeper版本不匹配问题