这一节了解一下ViewModel,ViewModel 类旨在以注重生命周期的方式存储和管理界面相关的数据。ViewModel 类让数据可在发生屏幕旋转等配置更改后继续留存。架构组件为界面控制器提供了 ViewModel 辅助程序类,该类负责为界面准备数据。在配置更改期间会自动保留 ViewModel对象,以便它们存储的数据立即可供下一个 activity 或 fragment 实例使用。ViewModel管理的数据为什么不会消失呢,是因为ViewModel的生命周期,如图:
例子:
ViewModel的另一个特点就是同一个Activity的Fragment之间可以使用ViewModel实现共享数据。来看一个小栗子:
第一步:添加依赖
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0' implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
如果不想findviewById,需添加
app下gradle:
plugins {
id 'kotlin-android-extensions'
}
项目下gradle:
classpath "org.jetbrains.kotlin:kotlin-android-extensions:1.3.61"
主要代码:
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class SharedViewModel: ViewModel() {
val inputNumber = MutableLiveData()
}
class InputFragment : Fragment() {
private var sharedViewModel: SharedViewModel? =null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_input, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
activity?.let {
sharedViewModel = ViewModelProviders.of(it).get(SharedViewModel::class.java)
}
et_input?.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun afterTextChanged(p0: Editable?) {
}
override fun onTextChanged(txt: CharSequence?, p1: Int, p2: Int, p3: Int) {
txt?.let {
var input = 0
if(txt.toString().isNotEmpty()) {
input = txt.toString().toInt()
}
sharedViewModel?.inputNumber?.postValue(input)
}
}
})
}
companion object {
}
}
class OutputFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_output, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
activity?.let {
val sharedViewModel = ViewModelProviders.of(it).get(SharedViewModel::class.java)
observeInput(sharedViewModel)
}
}
@SuppressLint("SetTextI18n")
private fun observeInput(sharedViewModel: SharedViewModel) {
sharedViewModel.inputNumber.observe(viewLifecycleOwner, Observer {
it?.let {
tv_output?.text = "2 x $it = ${2*it}"
}
})
}
companion object {
}
}
class ViewModelActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.viewmodel_main)
supportFragmentManager.beginTransaction().add(R.id.layout_top,InputFragment()).commit()
supportFragmentManager.beginTransaction().add(R.id.layout_bottom,OutputFragment()).commit()
val message = resources.getString(R.string.show_input)
val sharedViewModel = ViewModelProviders.of(this).get(SharedViewModel::class.java)
sharedViewModel.inputNumber.observe(this, Observer {
it?.let {
tv_show_input.text = "$message $it"
}
})
}
}
布局文件:
viewmodel_main.xml
fragment_input.xml
fragment_output.xml
strings.xml
Your input is
Enter a number
Result
参考:
官方文档:ViewModel
谷歌实验室



