智能客服
你问我答,随时在线为你解决问题
?: 表达式不为空就返回左边,为空返回右边
前面是手动去更新界面,如果在ViewModel中有子线程耗时逻辑,那么点击后更新的数据可能不变
绝大多数情况下,LiveData和ViewModel结合使用,可以包装任何类型的数据,然后在Activity中去观察这个数据,如果发生变化,就可以主动把数据变化通知给Activity
class MainViewModel(countReserved:Int) : ViewModel() {
var counter=MutableLiveData<Int>()//把counter修改为MutabelLiveData对象,这是一种可变的LiveData,他有三种用法:getValue(),setValue()(只能在主线程中调用),postValue()(在非主线程中调用给LiveData设置数据)
init{
counter.value=countReserved
}
fun plusOne(){
val count=counter.value?:0
counter.value=count+1
}
fun clear(){
counter.value=0
}
}
class MainActivity : AppCompatActivity() {
lateinit var viewModel:MainViewModel
lateinit var binding:ActivityMainBinding
lateinit var sp:SharedPreferences
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
binding=ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
sp=getPreferences(Context.MODE_PRIVATE)
val countReserved=sp.getInt("count_reserved",0)
viewModel=ViewModelProvider(this,MainViewModelFactory(countReserved))
.get(MainViewModel::class.java)
binding.plusOneBtn.setOnClickListener{
viewModel.plusOne()
}
binding.clearBtn.setOnClickListener {
viewModel.clear()
}
//observe观察数据变化,第一个参数是LifecycleOwner,继承了AppCompatActivity的Activity,或者是继承自androidx .fragment.app.Fragment的Fragment都是LifecycleOwner,可以直接传this,第二个参数是Observer接口,counter数据发生变化就会回调到这里,在这进行界面更新
viewModel.counter.observe(this, Observer{
count->binding.infoText.text=count.toString()
})
}
override fun onPause() {
super.onPause()
sp.edit {
putInt("count_reserved",viewModel.counter.value?:0)
}
}
但是这样会把counter这个可变的LiveData暴露给外部,可能被设置修改数据,
class MainViewModel(countReserved:Int) : ViewModel() {
val counter: LiveData<Int>//把counter声明为不可变的LiveData
get()=_counter//给get设置返回_counter, 这样只能调用counter获得_counter,但是不能给counter设置数据
//每次外部代码尝试读取 counter 属性的值时,get() 方法会被调用,并返回 _counter 的值。
private val _counter=MutableLiveData<Int>()//private,并且改名为 _counter
init{
_counter.value=countReserved
}
fun plusOne(){
val count=_counter.value?:0
_counter.value=count+1
}
fun clear(){
_counter.value=0
}
}
我要发帖子