jetpack之ViewModel的简单使用

VIewModel:VIew和Model间的媒婆

ViewModel是jetpack下面比较常用的组件。他是MVVM架构中的重要组成部分,承担着类似MVP架构中Presenter的作用。

 ViewModel:我行我素的生命周期

jetpack之ViewModel的简单使用_第1张图片

由此图片我们可以看出,ViewModel的生命周期犹如Service一般,贯穿Activity的整个生命周期。这也就是它为什么能够在即使屏幕旋转之后,也能保存下来数据。因为在它的创建在onCreate的时候就已经创建好了,所以,不管activity如何如何,他依旧我行我素,算是一个有个性的组件。

ViewModel的代码示例1:

NumViewModel.kt

class NumViewModel : ViewModel() {
    var num = 0
}

OneActivity.kt

class MainActivity : AppCompatActivity() {
    private lateinit var numViewModel: NumViewModel
    private lateinit var tv:TextView
    @SuppressLint("SetTextI18n", "MissingInflatedId")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        tv = findViewById(R.id.num_tv)
        //viewmodel的创建
        numViewModel = ViewModelProvider(this)[NumViewModel::class.java]
        tv.text = numViewModel.num.toString()
    }

    @SuppressLint("SetTextI18n")
    fun add(view: View) { //自定义button点击事件
        numViewModel.num++
        tv.text = numViewModel.num.toString()
    }
}

activity_one.xml




    

ViewModel采用工厂模式进行创建,让ViewModel整个生命周期设置为Activity级别的ViewModel。

如果直接实例化NumViewModel是没有用的,在之后的hilt依赖注入会让代码更加解耦

代码运行演示

jetpack之ViewModel的简单使用_第2张图片

ViewModel的代码实例2

OneFragment.kt

class OneFragment : Fragment() {
    private lateinit var btn:Button
    private lateinit var tv:TextView
    private lateinit var numViewModel:NumViewModel
    @SuppressLint("MissingInflatedId", "SetTextI18n")
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_one,container,false)
        numViewModel = ViewModelProvider(requireActivity())[NumViewModel::class.java]
        btn = view.findViewById(R.id.fragment1_btn)
        tv = view.findViewById(R.id.fragment1_num_tv)
        tv.text =numViewModel.num.toString()
        btn.setOnClickListener {
            ++numViewModel.num
            tv.text =(numViewModel.num).toString()
        }
        return view
    }

}

TwoFragment.kt

class TwoFragment : Fragment() {
    private lateinit var btn: Button
    private lateinit var tv: TextView
    private lateinit var numViewModel:NumViewModel
    @SuppressLint("MissingInflatedId", "SetTextI18n")
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_second,container,false)
        numViewModel = ViewModelProvider(requireActivity())[NumViewModel::class.java]
        btn = view.findViewById(R.id.fragment2_btn)
        tv = view.findViewById(R.id.fragment2_num_tv)
        tv.text =numViewModel.num.toString()
        btn.setOnClickListener {
            tv.text =(++numViewModel.num).toString()
        }
        return view
    }

}

我们注意到以下代码

numViewModel = ViewModelProvider(requireActivity())[NumViewModel::class.java]

此代码中我将此viewmodel设置为activity级别,这样,就能实现fragment中的数据共享,但是,我们发现了一个问题,那就是,只要不触发点击事件,就无法更新UI组件,所以,livedata的出现弥补了ViewModel的不足。

fragment_second.xml



    

fragment_one.xml



    

SecondActivity.kt

class SecondActivity: AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)
    }
}

activity_second.xml.



    

代码演示

jetpack之ViewModel的简单使用_第3张图片 

你可能感兴趣的:(kotlin,android,android,jetpack)