Android mvvm之LiveData原理案例详解

yizhihongxing

Android MVVM之LiveData原理案例详解

什么是LiveData

在 Android 架构组件中,LiveData 是一个可观察的数据持有者,它可以感知 Activity、Fragment 等生命周期的变化,并在数据发生变化时派发出新的值。

LiveData 原理

在数据更新时,LiveData 会通知观察它的观察者,这种通知是安全的,即无论观察者当前处于哪个组件或生命周期状态,都可以接收到通知。LiveData 可以保证活动组件(如 Activity 和 Fragment)处于前台时,观察者会收到数据更新的通知。

LiveData 是基于观察者模式实现的。LiveData 持有一个观察者列表,当数据改变时依次通知观察者更新数据。

如何使用 LiveData

LiveData 使用起来非常简单,我们只需要在 ViewModel 中定义一个 LiveData 对象,并在需要更新时调用 setValue() 方法即可。Observer 会在数据更新时自动获取最新的数据。

例如,我们在 ViewModel 中定义一个 LiveData 对象,用于更新用户信息:

class UserViewModel : ViewModel() {

    val userLiveData = MutableLiveData<User>()

    fun updateUser() {
        // 更新用户信息
        userLiveData.value = user
    }
}

在 Activity 或 Fragment 中,我们可以通过调用 observe() 方法观察 LiveData 的变化:

class UserActivity : AppCompatActivity() {

    private lateinit var userViewModel: UserViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_user)

        userViewModel = ViewModelProvider(this).get(UserViewModel::class.java)

        userViewModel.userLiveData.observe(this, Observer { user ->
            // 更新 UI
            updateUI(user)
        })
    }

    // 更新 UI
    private fun updateUI(user: User) {
        // ...
    }
}

LiveData 的优势

LiveData 有很多优势。以下是一些常见的优点:

  • 生命周期感知:LiveData 可以感知生命周期,自动管理生命周期,避免了内存泄漏。
  • 线程安全:LiveData 会在主线程通知观察者更新数据,避免了多线程问题。
  • 基于观察者模式:LiveData 可以自动通知观察者更新数据,无需手动刷新 UI。
  • 可以用于跨组件通信:LiveData 可以用于不同组件之间的数据传递,比如 Activity 和 Fragment 之间的数据共享。
  • 可以避免不必要的更新:LiveData 可以避免数据更新时不必要的 UI 刷新,提高性能。

LiveData 示例

下面是两个 LiveData 的示例:

示例一:计数器

在 ViewModel 中定义一个 LiveData 对象 countLiveData,用于更新计数器:

class CounterViewModel : ViewModel() {

    private val countLiveData = MutableLiveData<Int>()

    init {
        countLiveData.value = 0
    }

    fun increase() {
        countLiveData.value = countLiveData.value?.plus(1)
    }

    fun decrease() {
        countLiveData.value = countLiveData.value?.minus(1)
    }

    fun getCountLiveData(): LiveData<Int> {
        return countLiveData
    }
}

在 Activity 中观察 countLiveData 的变化,更新 UI:

class CounterActivity : AppCompatActivity() {

    private lateinit var counterViewModel: CounterViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_counter)

        counterViewModel = ViewModelProvider(this).get(CounterViewModel::class.java)

        counterViewModel.getCountLiveData().observe(this, Observer { count ->
            countTextView.text = count.toString()
        })

        addButton.setOnClickListener {
            counterViewModel.increase()
        }

        minusButton.setOnClickListener {
            counterViewModel.decrease()
        }
    }
}

示例二:导航栏

在 ViewModel 中定义一个 LiveData 对象 navLiveData,用于更新导航栏:

class NavViewModel : ViewModel() {

    private val navLiveData = MutableLiveData<Nav>()

    fun switchNav(nav: Nav) {
        navLiveData.value = nav
    }

    fun getNavLiveData(): LiveData<Nav> {
        return navLiveData
    }
}

在 Fragment 中观察 navLiveData 的变化,更新导航栏:

class NavFragment : Fragment() {

    private lateinit var navViewModel: NavViewModel

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_nav, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        navViewModel = ViewModelProvider(requireActivity()).get(NavViewModel::class.java)

        navViewModel.getNavLiveData().observe(viewLifecycleOwner, Observer { nav ->
            // 更新导航栏
            navTextView.text = nav.title
            navImageView.setImageResource(nav.icon)
        })

        homeButton.setOnClickListener {
            navViewModel.switchNav(Nav("首页", R.drawable.ic_home))
        }

        settingButton.setOnClickListener {
            navViewModel.switchNav(Nav("设置", R.drawable.ic_setting))
        }
    }
}

总结

使用 LiveData 可以方便地实现数据监听、UI 刷新等操作,避免了很多手动代码。同时,LiveData 可以避免线程安全、生命周期管理等问题,为我们带来了更好的开发体验。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android mvvm之LiveData原理案例详解 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • stm32按键识别

    描述 在STM32单片机开发中,按键识别是一个常见的需求。本攻略将介绍如何使用STM32 HAL库实现按键识别,包括按键硬件连接、按键扫描、按键中断处理等。同时本攻略将提供两个示例说明,分别介绍如何使用按键控制LED灯的开关和如何使用按键控制LCD屏的内容。 按键硬件连接 以下是按键硬件连接的步骤: 连接按键 首先,需要将按键连接STM32单片机的GPIO引…

    other 2023年5月7日
    00
  • iOS12 beta5固件在哪下载 ios12开发者预览版beta5固件下载地址大全

    以下是“iOS12 beta5固件在哪下载”的完整攻略: 1. 了解iOS12 beta5 在下载iOS12 beta5固件之前,首先需要了解一些关于iOS12 beta5的基本信息。iOS12 beta5是面向开发者的预览版,其中可能包含一些尚未解决的bug和问题。因此,建议只有开发者和专业用户在测试环境下使用iOS12 beta5。如果你只是一般用户,则…

    other 2023年6月26日
    00
  • MybatisPlus多表连接查询的问题及解决方案

    MybatisPlus是基于Mybatis的扩展库,可以在Mybatis的基础上进一步简化CRUD操作。然而,MybatisPlus对于多表连接查询支持并不友好,需要我们自己手动编写SQL语句来实现。下面,我们将详细讲解MybatisPlus多表连接查询的问题及解决方案。 问题描述 MybatisPlus默认使用了Java对象和数据库表的简单映射,对于单表的…

    other 2023年6月26日
    00
  • win10 Build 9865怎么更新升级? win10 9865下载更新教程

    Win10 Build 9865 更新升级攻略 1. 检查更新 首先,我们需要检查是否有可用的更新。请按照以下步骤进行操作: 打开“设置”应用程序。你可以通过点击任务栏上的“开始”按钮,然后点击“设置”图标来打开它。 在“设置”窗口中,点击“更新和安全”选项。 在左侧导航栏中,选择“Windows 更新”。 在右侧窗格中,点击“检查更新”按钮。 示例说明:如…

    other 2023年8月3日
    00
  • layui表格自定义toolbar

    当然,我很乐意为您提供有关“locate命令详解”的完整攻略。以下是详细的步骤和两个示例: 1 locate命令详解 locate命令是Linux系统中的一个命令行工具,用于快速查找文件。它可以在文件系统中搜索文件名,而不是搜索文件内容。locate命令使用一个数据库来存储文件名和路径信息,因此它比使用find命令更快。 2 locate命令的使用 以下是使…

    other 2023年5月6日
    00
  • 如何修复macbookpro过热:保持macbook散热的13个技巧

    如何修复MacBook Pro过热:保持MacBook散热的13个技巧 MacBook Pro过热是一个常见的问题,它可能会导致系统溃或损坏硬件。以下是一些保持MacBook散热技巧,以帮助您修复MacBook Pro过热问题。 1 清洁散热口和风扇 MacBook Pro的散热口和风可能会被灰尘和污垢堵塞,导致散热不良。您可以使用吸尘器或压缩空气清洁它们。…

    other 2023年5月9日
    00
  • Java调用windows系统的CMD命令并启动新程序

    下面是完整攻略: 1. 通过Runtime.getRuntime().exec()方法调用CMD命令 Java可以通过对Runtime.getRuntime().exec()方法的调用来启动CMD命令,并通过输入输出流来与CMD命令进行交互。具体步骤如下: 创建一个Process对象,通过执行CMD命令来启动新程序。 通过Process对象的getInput…

    other 2023年6月26日
    00
  • 基于android布局中的常用占位符介绍

    当在Android布局中设计界面时,常常需要使用占位符来指定视图的位置和大小。下面是一些常用的占位符介绍及其使用方法: @+id/placeholder:这是最常见的占位符,用于指定一个视图的唯一标识符。通过在布局文件中使用android:id属性,可以为视图指定一个唯一的ID。例如: <Button android:id=\"@+id/my…

    other 2023年9月7日
    00
合作推广
合作推广
分享本页
返回顶部