Android mvvm之LiveData原理案例详解

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日

相关文章

  • 使用microsoftsynctoy文件同步/备份自动化处理

    以下是使用Microsoft SyncToy文件同步/备份自动化处理的攻略,包含两个示例: 什么是Microsoft SyncToy? Microsoft SyncToy是一个免费的Windows实用程序,可用于自动化处理文件同步备。它可以帮助您快速、轻松地将文件从一个位置复制到另一个位置,或者将文件备份到外部硬盘或网络动器。 如何使用 SyncToy进行文…

    other 2023年5月6日
    00
  • VS2010 自定义用户控件未出现在工具箱的解决方案

    下面是详细讲解“VS2010 自定义用户控件未出现在工具箱的解决方案”的完整攻略。 问题现象描述 在使用 Visual Studio 2010 开发 .NET 应用程序时,当我们自定义一个用户控件并在项目中引用后,可能会出现该用户控件未出现在工具箱中的情况。 解决方案 方法一:手动添加控件到工具箱 如果用户控件未出现在工具箱中,我们可以手动将其添加到工具箱中…

    other 2023年6月27日
    00
  • C++实现一个简单的SOAP客户端

    为了实现一个简单的SOAP客户端,我们需要按照以下步骤进行操作: 步骤一:安装必要的库和工具 SOAP是一种基于XML的Web服务协议,我们需要用到的是SOAP库。在C++中,我们有很多不同的SOAP库可供选择,比如gSOAP、Apache Axis C++等等。在这里,我们以gSOAP为例进行说明。 下载并安装gSOAP库,可以从官网http://www.…

    other 2023年6月26日
    00
  • win10预览版怎么安装?win10预览版下载地址

    Win10预览版安装攻略 Win10预览版是微软提供给用户提前体验最新功能和改进的版本。以下是安装Win10预览版的详细攻略,包括下载地址和示例说明。 步骤一:下载Win10预览版 首先,你需要下载Win10预览版的安装文件。微软官方提供了下载页面,你可以在以下地址找到最新的预览版下载链接: Win10预览版下载地址 步骤二:选择适合的版本 在下载页面上,你…

    other 2023年8月4日
    00
  • 关于python:pycharm“运行配置” 要求“脚本参数”

    关于Python: PyCharm“运行配置”要求“脚本参数”的攻略 在使用PyCharm进行Python开发时,我们经常需要在运行Python脚本时传递一些参数。本攻略将详细介绍如何在PyCharm中配置脚本参数,并提供两个示例。 方法1:使用PyCharm的“运行配置”功能 PyCharm提供了一个“运行配置”功能,可以方便地配置Python脚本的运行参…

    other 2023年5月9日
    00
  • MyBatis-Plus通过插件将数据库表生成Entiry,Mapper.xml,Mapper.class的方式

    以下是使用MyBatis-Plus通过插件将数据库表生成Entity、Mapper.xml和Mapper.class的方式的完整攻略: 首先,确保您的项目中已经引入了MyBatis-Plus的依赖项。您可以在项目的pom.xml文件中添加以下依赖项: <dependency> <groupId>com.baomidou</gro…

    other 2023年10月14日
    00
  • iOS9 beta1固件下载地址 苹果iOS9 beta1固件下载(附网盘下载)

    iOS9 beta1固件下载攻略 苹果的iOS9 beta1固件是开发者版本,提供给开发者测试和调试新功能。以下是下载iOS9 beta1固件的详细攻略。 步骤一:注册为苹果开发者 在下载iOS9 beta1固件之前,您需要注册为苹果开发者。请按照以下步骤完成注册: 访问苹果开发者网站。 点击\”加入Apple开发者计划\”按钮。 按照网站上的指示填写个人信…

    other 2023年8月4日
    00
  • python 中的命名空间,你真的了解吗?

    Python 中的命名空间 在 Python 中,命名空间是一个用于存储变量名称和其对应值的系统。它允许我们在代码中使用不同的名称来引用不同的变量,以避免命名冲突和混淆。理解命名空间的概念对于编写清晰、可维护的代码非常重要。 全局命名空间 全局命名空间是在 Python 程序启动时创建的,它包含了所有全局变量的名称和值。全局命名空间在整个程序执行期间都是可用…

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