首页 > 其他分享 >Jetpack基础(LifeCycle && ViewModel && LiveData)

Jetpack基础(LifeCycle && ViewModel && LiveData)

时间:2024-12-09 21:31:06浏览次数:8  
标签:counter Jetpack ViewModel LiveData countReserved && Activity fun model

Jetpack

什么是Jetpack

Jetpack是一个由多个库组成的套件,可帮助开发者遵循最佳做法,减少样板代码并编写可在各种Android版本和设备中一致运行的代码
在这里插入图片描述

  • 遵循最佳做法
  • 消除样板代码
  • 减少不一致

LifeCycle

解耦问题:减少系统组件(Activity等)与用户自定义组件的耦合程度
让类能轻松感知到Activity的声明周期的同时不需要在Activity中编写大量逻辑代码

用法

  • 新建类,实现LifecycleObserve接口
class MyObserver : LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun activityStart(){
        Log.d("MyObserver","activityStart")
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun activityStop(){
        Log.d("MyObserver","activityStop")
    }
}
  • 可以看到,我们在方法使用了@OnLifecycleEvent注解,并传入了一种生命周期事件。生命周期事件的类型共7种:ON_CREATE、ON_START、ON_RESUME、ON_PAUSE、ON_STOP、ON_DESTROY分别匹配Activity中相应的生命周期回调;其次关于ON_ANY类型,表示可以匹配Activity的任何生命周期回调。
  • Activity中调用
override fun onCreate (savedInstanceState: Bundle?) {
	super.onCreate (savedInstanceState)
	setContentView (R.layout.activity_main)
	...
	lifecycle.addObserver (MyObserver())
}
  • lifecycle.currentState 主动获取当前的生命周期状态,其返回类型是个枚举(INITIALIZED、DESTROYED、CREATED、STARTED、RESUMED这5种状态类型)
    在这里插入图片描述

ViewModel

缓存状态,可在配置更改后持久保留响应状态,这意味着在Activity之间导航时或进行配置更改后(例如旋转屏幕时),界面将无需重新提取数据。

优势

  • 允许持久保留界面状态
  • 提供对业务逻辑的访问权限

用法

  • 创建自己的viewModel
class MainViewModel : ViewModel () {
	var counter = 0
}
  • Activity中实例化viewModel
class MainActivity : AppCompatActivity () {
	lateinit var viewModel : MainViewModel
	override fun onCreate (savedInstanceState : Bundle?) {
		super.onCreate (savedInstanceState)
		setContentView (R.layout.activity.main)
		viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
		plusOneBtn.setOnClickListener {
			viewModel.counter++
			refreshCounter()
		}
		refreshCounter()
	}
	private fun refreshCounter() {
		infoText.text = viewModel.counter.toString()
	}
}

目前推荐写法:

model = ViewModelProvider(this)[MyViewModel::class.java]

向ViewModel传值

  • 新建类 实现ViewModelProvider.Factory的接口
新建类 实现ViewModelProvider.Factory的接口
class MainViewModelFactory(private val countReserved: Int): ViewModelProvider.Factory {
//    create方法执行时机和Activity的生命周期无关
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
         return MyViewModel(countReserved) as T
    }
}
  • 修改MyViewModel
//增加传入参数 countReserved
class MyViewModel(countReserved: Int):ViewModel (){
    var counter = countReserved
}
  • Activity
class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
//    private val model: MyViewModel by ViewModels()
    private lateinit var model: MyViewModel
    private lateinit var sp: SharedPreferences
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        sp = getPreferences(Context.MODE_PRIVATE)
        val countReserved = sp.getInt("count_reserved",0)
//        增加参数 MainViewModelFactory 将countReserved 传给MainViewModelFactory 的构造函数
        model = ViewModelProvider(this,
        MainViewModelFactory(countReserved))[MyViewModel::class.java]
        binding.apply {
            btnAdd.setOnClickListener {
                model.counter++
                refreshCounter()
            }
            clearBtn.setOnClickListener{
                model.counter = 0
                refreshCounter()
            }
        }
        refreshCounter()
    }
// 对counter 进行保存
    override fun onPause() {
        super.onPause()
        sp.edit {
            putInt("count_reserved",model.counter)
        }
    }
    private fun refreshCounter() {
        binding.textView.text = model.counter.toString()
    }
}

ViewModel生命周期

在这里插入图片描述

LiveData

LiveData 是Jetpact提供的一种响应式编程组件
主要用于UI组件的数据绑定 当LiveData持有的数据发生变化时,所有已注册的观察者都会自动收到通知 使得UI可以自动响应数据变化

MutableLiveData 是一种可变的LiveData 有三种读写数据的方法:getValue()、setValue()和postValue() 其中postValue用于非主线程给LiveData设置数据

用法

  • 推荐写法:永远只暴露不可变的LiveData给外部
class MyViewModel(countReserved: Int):ViewModel (){
//    使用LiveData改造
//    counter 为不可变 LiveData
    val counter: LiveData<Int>
        get() = _counter
//    _counter对外部 不可见
    private val _counter = MutableLiveData<Int>()
    init {
        _counter.value = countReserved
    }
    fun plusone(){
        val count = counter.value ?: 0
        _counter.value = count + 1
    }
    fun clear(){
        _counter.value = 0
    }
}
  • Activity中调用
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("MainActivity1", "onCreate")
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        lifecycle.addObserver(MyObserver())
        sp = getPreferences(Context.MODE_PRIVATE)
        val countReserved = sp.getInt("count_reserved", 0)
//        增加参数 MainViewModelFactory 将countReserved 传给MainViewModelFactory 的构造函数
        model =
            ViewModelProvider(this, MainViewModelFactory(countReserved))[MyViewModel::class.java]
        binding.apply {
            btnAdd.setOnClickListener {
                model.plusone()
            }
            clearBtn.setOnClickListener {

                model.clear()
            }
            model.counter.observe(this@MainActivity){ count ->
                textView.text = count.toString()
            }
        }
    }

map和swichMap方法

  • map:将实际包含数据的LiveData和仅用于观察数据的LiveData进行转换
  • switchMap:viewmodel中的某个LiveData对象是调用另外的方法获取的,可以使用SwitchMap,将该对象转换成可观察的LiveData对象

标签:counter,Jetpack,ViewModel,LiveData,countReserved,&&,Activity,fun,model
From: https://blog.csdn.net/qq_53092981/article/details/144352790

相关文章

  • Jetpack Compose 入门与深入理解(一)
    JetpackCompose命令式UI(ImperativeUI)什么是命令式UI命令式UI的缺点声明式UI(DeclarativeUI)什么是声明式UI声明式UI的优点声明式UI发展历程命令式UI(ImperativeUI)什么是命令式UI在Android开发中,我们目前采用命令式UI开发模式<!--代码经过简化--><LinearLa......
  • Jetpack Compose学习(14)——ConstraintLayout约束布局使用
    原文地址:JetpackCompose学习(14)——ConstraintLayout约束布局使用-Stars-One的杂货小窝本文阅读之前,需要了解ConstraintLayout的使用!各位可查阅我的ConstraintLayout使用一文本系列以往文章请查看此分类链接Jetpackcompose学习引入依赖implementation("androidx.c......
  • Jetpack Compose 如何适配不同分辨率设备
    文章目录前言1、获取屏幕信息2、使用响应式布局适配屏幕2.1动态调整布局3、精准适配特定分辨率4、多分辨率预览5、针对屏幕密度的适配6、实战:流式网格布局适配(例子)总结前言在移动开发中,适配不同分辨率和屏幕大小是不可避免的挑战。JetpackCompose提供了更现......
  • Jetpack Compose 如何布局解析
    文章目录前言1、@Composable函数的编译器处理2、UI树的构建与状态管理3、测量与布局4、重组机制(Recomposition)5、性能优化机制总结前言JetpackCompose的布局解析包含以下核心环节:编译器处理、UI树的构建与状态管理、测量与布局、以及重组机制。以下是结合源码......
  • Jetpack-ViewModel+LiveData+DataBinding
    1.ViewModel解决问题:瞬态数据丢失异步调用内存泄漏类膨胀提高维护难度和测试难度作用:介于View视图和Model数据模型之间桥梁使视图和数据能够分离,也能保持通信publicclassMainActivityextendsAppCompatActivity{privateTextViewtextView;privateMy......
  • Jetpack Compose 基本布局(7)
    导读大纲1.1探索基本布局1.1.1布局介绍1.1.2定位和尺寸的修改器1.2组合可组合元素1.2.1在布局内组合可组合元素1.2.2组织可组合元素的最佳实践1.2.3真实世界的场景1.1探索基本布局布局是JetpackComposeUI的支柱它们提供在屏幕上组织和排列可组合......
  • 带你了解Android Jetpack库中的依赖注入框架:Hilt
    本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点Hilt概述Hilt是Google推出的一种用于Android的依赖注入(DependencyInjection,DI)框架,构建于Dagger之上,旨在简化Android应用中的依赖注入过程。通过Hilt,你可以更轻松......
  • 聊一下Jetpack AppStartUp的使用和原理。
    AppStartup是AndroidJetpack中的一个库,用于在应用启动时初始化组件,能简化启动序列并显式设置初始化依赖顺序,从而提高应用的启动速度。以下是关于AppStartup的使用和原理的介绍:使用方法添加依赖:在项目的模块级build.gradle文件中添加对AppStartup的依赖。implementatio......
  • WPF-Prism中View和ViewModel的关联
    1、在MainWindow.xaml中进行Prism命名空间的引入以及ViewModelLocator.AutoWireViewModel属性的设置需要注意,AutoWireViewModel默认就是为True,表示自动关联ViewModel,因此这个命名空间引入以及设置属性的步骤是可以省略的2、通过ViewModelLocator进行View与ViewModel层的自动关......
  • Jetpack业务架构—四件套(Lifecycle、ViewModel、LiveData、DataBinding)
            Jetpack是一个由多个库组成的套件,可帮助开发者遵循最佳做法、减少样板代码并编写可在各种Android版本和设备中一致运行的代码,让开发者可将精力集中于真正重要的编码工作。1. AndroidJetpack组件的优势:        Jetpack推出的主要目的是为了能够......