当前位置: 首页 > news >正文

Android ViewPager2+Fragment viewModelScope问题

文章目录

  • Android ViewPager2+Fragment viewModelScope问题
    • 核心代码
    • 问题
    • 解决一
    • 解决二
    • 解决三

Android ViewPager2+Fragment viewModelScope问题

核心代码

class MainActivity : AppCompatActivity() {private lateinit var tabLayout: TabLayoutprivate lateinit var viewPager2: ViewPager2private val titles = mutableListOf<String>()private val fragments = mutableListOf<MyFragment>()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)tabLayout = findViewById(R.id.tab_layout)viewPager2 = findViewById(R.id.view_pager2)for (i in 'A'..'F') {titles.add(i.toString())fragments.add(MyFragment.newInstance(i.toString()))}viewPager2.adapter = MyAdapter(this, fragments)viewPager2.offscreenPageLimit = 1TabLayoutMediator(tabLayout,viewPager2,object : TabLayoutMediator.TabConfigurationStrategy {override fun onConfigureTab(tab: TabLayout.Tab,position: Int) {tab.text = titles[position]}}).attach()}class MyAdapter(fragmentActivity: FragmentActivity, val fragments: List<MyFragment>) :FragmentStateAdapter(fragmentActivity) {override fun createFragment(position: Int): Fragment {return fragments[position]}override fun getItemCount(): Int {return fragments.size}}
}
class MyFragment : Fragment() {private val viewModel: MyFragmentViewModel by viewModels()private var title = ""companion object {fun newInstance(title: String) =MyFragment().apply {arguments = Bundle().apply {putString("title", title)}}}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)arguments?.let {title = it.getString("title") ?: ""}}override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View {Log.e("TAG", "Fragment ${title} 创建")return inflater.inflate(R.layout.fragment_my, container, false)}override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)val textView = view.findViewById<TextView>(R.id.text_view)textView.text = "Fragment $title"viewModel.load(title)}override fun onDestroyView() {super.onDestroyView()Log.e("TAG", "Fragment ${title} 销毁")}
}
class MyFragmentViewModel : ViewModel() {fun load(title: String) {Log.e("TAG", "$title 开始加载")Log.e("TAG", "$title viewModelScope是否可用:${viewModelScope.isActive}")viewModelScope.launch {delay(1000L)Log.e("TAG", "$title 结束加载")}}
}

问题

首先点击 Fragment A,会执行 Fragment 的 ViewModel 的 load() 方法。接着点击 Fragment F,Fragment A 会被销毁掉,然后再点击 Fragment A,这时 Fragment A会被重新创建,而对应的 ViewModel 的 isActive 却是 false,导致 viewModelScope.launch 无法执行。

解决一

使用 Activity 的ViewModel。

class MyFragment : Fragment() {private val viewModel: MyFragmentViewModel by activityViewModels()
}

解决二

使用 Fragment 中的 lifecycleScope。

class MyFragment : Fragment() {override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)val textView = view.findViewById<TextView>(R.id.text_view)textView.text = "Fragment $title"viewModel.load(lifecycleScope, title)}
}

解决三

不缓存实例,每次都重新创建 Fragment。

class MainActivity : AppCompatActivity() {private val fragments = mutableListOf<() -> Fragment>()override fun onCreate(savedInstanceState: Bundle?) {for (i in 'A'..'F') {titles.add(i.toString())fragments.add({ MyFragment.newInstance(i.toString()) })}}class MyAdapter(fragmentActivity: FragmentActivity, val fragments: List<() -> Fragment>) :FragmentStateAdapter(fragmentActivity) {override fun createFragment(position: Int): Fragment {return fragments[position].invoke()}override fun getItemCount(): Int {return fragments.size}}
}
http://www.dtcms.com/a/333498.html

相关文章:

  • 在 Vue2 中使用 pdf.js + pdf-lib 实现 PDF 预览、手写签名、文字批注与高保真导出
  • Java零基础笔记18(Java编程核心:Java网络编程—数据通信方案)
  • leetcode 刷题1
  • SysGetVariableString函数
  • 【python实用小脚本-187】Python一键批量改PDF文字:拖进来秒出新文件——再也不用Acrobat来回导
  • 详解 k 近邻(KNN)算法:原理、实践与调优 —— 以鸢尾花分类为例
  • JUC LongAdder并发计数器设计
  • 指针操作:从到*的深度指南
  • JavaWeb开发_Day13
  • Cortex-Debug和openocd之间的关系?如何协同工作?
  • 《人形机器人的觉醒:技术革命与碳基未来》——触觉反馈系统:电子皮肤的概念、种类、原理及在机器中的应用
  • 攻防世界—fakebook(两种方法)
  • docker重启或系统重启后harbor自动启动
  • 深入理解C++正则表达式:从基础到实践
  • ReasonRank:从关键词匹配到逻辑推理,排序准确性大幅超越传统方法
  • Apifox接口测试工具
  • Unity输入系统:旧版Input_System
  • 第四章:大模型(LLM)】06.langchain原理-(3)langchain 数据连接方法
  • kubernetes(4) 微服务
  • 前往中世纪 送修改器(Going Medieval)免安装中文版
  • AI大模型配置项
  • 【mysql数据库全部重点知识】
  • 企业级时序数据库选型指南:从传统架构向智能时序数据管理的转型之路
  • 昆仑万维重磅发布Mureka V7.5与MoE-TTS,AI音乐与语音合成再升级!
  • 嵌入式学习 day52 IMX6ULL裸机开发-I2C
  • 基于Spring Boot的智能民宿预订与游玩系统设计与实现 民宿管理系统 民宿预订系统 民宿订房系统
  • 蓝桥杯 二叉树
  • [ CSS 前端 ] 网页内容的修饰
  • linux下找到指定目录下最新日期log文件
  • liteflow