Android Jetpack组件中LiveData的优劣

目录
  • LiveData和ViewModel的关系
  • LiveData的优势
  • demo演示

LiveData和ViewModel的关系

在 ViewModel 中的数据发生变化时,LiveData通知页面。LiveData 是要和 ViewModel 一起使用的。

LiveData的优势

确保界面符合数据状态

不会发生内存泄漏

不会因 Activity 停止而导致崩溃

不再需要手动处理生命周期

数据始终保持最新状态

适当的配置更改

共享资源

demo演示

使用 ViewModel + LiveData, 实现 Fragment 的通信。上面演示界面的两个seekBar,分别位于两个 Fragment 中(FirstFragment/SecondFragment, 都在 MainActivity 中),我们要实现拖动其中任何一个seekBar,另外一个seekBar 的值也会随之改变。即要实现两个 Fragment 之间的通信。

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <fragment
        android:id="@+id/first_fragment"
        android:name="com.example.livedata2.FirstFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@+id/guideline"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />
    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_begin="366dp" />
    <fragment
        android:id="@+id/second_fragment"
        android:name="com.example.livedata2.SecondFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintTop_toBottomOf="@+id/guideline"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        />
</androidx.constraintlayout.widget.ConstraintLayout>

fragment_first.xml / fragment_second.xml(它们两个布局一样)

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SecondFragment">
    <SeekBar
        android:id="@+id/seekBar"
        android:layout_width="0dp"
        android:max="100"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

MyViewModel.java

LiveData 类型数据是写在 ViewModel 中的。MutableLiveData 继承自 LiveData,是它的子类,LiveData 是一个抽象类。

package com.example.livedata2;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class MyViewModel extends ViewModel {
    private MutableLiveData<Integer> progress;
    public MutableLiveData<Integer> getProgress() {
        if (progress == null) {
            progress = new MutableLiveData<>();
            progress.setValue(0);
        }
        return progress;
    }
}

上面代码定义了一个 LivaData 类型的 progress,通过监听它的值的改变,来动态改变 view 界面显示的内容。

FirstFragment.java

package com.example.livedata2;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SeekBar;
import java.util.Objects;
public class FirstFragment extends Fragment {
    private SeekBar seekBar;
    private MyViewModel viewModel;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View root = inflater.inflate(R.layout.fragment_f_irst, container, false);
        seekBar = root.findViewById(R.id.seekBar);
        // TODO 获取到 MyViewModel 对象
        viewModel = new ViewModelProvider(requireActivity(),
                new ViewModelProvider.AndroidViewModelFactory(requireActivity().getApplication())).get(MyViewModel.class);
        // TODO  监听 (LiveData)progress 数据的改变
        viewModel.getProgress().observe(requireActivity(), new Observer<Integer>() {
            @Override
            public void onChanged(Integer i) {
                seekBar.setProgress(i);
            }
        });
        // TODO 当拖动 seekBar 时,改变 (LiveData)progress 的值
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                viewModel.getProgress().setValue(progress);
            }
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
        });
        return root;
    }
}

当用户手动拖动 seekBar 时,SeekBar.setOnSeekBarChangeListener.onProgressChanged() 方法里将拖动的值赋给(LiveData)progress,然后 viewModel.getProgress().observe() 监听(LiveData)progress 值的改变,然后再显示在 view 上。

FirstFragment.java

SecondFragment 里的内容和 FirstFragment 里的内容一样,只是加载的布局不一样,如下:

View root = inflater.inflate(R.layout.fragment_second, container, false);

因为FirstFragment 与SecondFragment 共用了MyViewModel里的(LiveData)progress,然后显示在 view 上。所以当我拖动任意一个 seekBar 而改变了(LiveData)progress 的值,另外一个 Fragment 的 seekBar 也会随着改变。从而实现了两个 Fragment 之间的通信。

MainActivity.java

package com.example.livedata2;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

到此这篇关于Android Jetpack组件中LiveData的优劣的文章就介绍到这了,更多相关Android LiveData内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android Jetpack 组件LiveData源码解析

    目录 前言 基本使用 疑问 源码分析 Observer ObserverWrapper LifecycleBoundObserver MutableLiveData postValue setValue 问题答疑 LiveData 特性引出的问题 问题解决 最后 前言 本文来分析下 LiveData 的源码,以及其在实际开发中的一些问题. 基本使用 一般来说 LiveData 都会配合 ViewModel 使用,篇幅原因关于 ViewModel 的内容将在后续博客中分析,目前可以将 ViewMo

  • Android开发Jetpack组件ViewModel与LiveData使用讲解

    目录 一.ViewModel 1.解决的问题 2.注意点事项 3.ViewModel案例 二.LiveData 1.viewmodel+livedata使用案例 2.viewmodel+livedata Android Jetpack之LifeCycle 一.ViewModel ViewModel是介于View(视图)和Model(数据模型)之间的中间层,能够使视图和数据分离,又能提供视图和数据之间的通信.如图所示: 1.解决的问题 屏幕翻转后页面数据的丢失: 异步调用导致的内存泄露: 类膨胀提

  • Android Jetpack 狠活Lifecycles与LiveData使用详解

    目录 前言 正篇 结语 前言 今天在工作时,测试突然提了一个Bug给我,要求我将APP中某活动页面的UI界面要根据用户在由此页面跳转的下个页面操作,在返回时要实时更新. 在检查代码时,发现我已经对界面可变数据用LiveData去观测,但由于页面变化后并没有重新初始化UI,所以我放在初始化UI的请求根本没有起效,如上图所示例子,在进入下一个页面如若关闭开关,返回时无法及时更新,于是我便想到了安卓科技与狠活Lifecycles,去监听onResume,在resume时用livedata去post数据

  • Android Jetpack库剖析之LiveData组件篇

    目录 LiveData简介 LiveData用法 数据订阅过程 PostValue过程 SetValue过程 生命周期变化 LiveData简介 在日常安卓开发中,一些耗时的操比如列网络请求,数据库读写都不能在主线程执行,必须开一条子线程去执行这些耗时操作,但我们往往需要在这些耗时操作执行完毕后更新UI,但安卓不能在子线程进行UI的更新,这时我们只能通过创建一个Handler来切回到主线程进行UI的更新,直到LiveData出现,LiveData是一个可被观察的数据容器,它将数据包装起来,使数据

  • Android开发Jetpack组件LiveData使用讲解

    目录 LiveData概述 LiveData优势 共享资源 LiveData使用 1 LiveData基本使用 2 Transformations.map() 3 Transformations.switchMap() 4 MediatorLiveData.addSource()合并数据 LiveData概述 LiveData 是一种可观察的数据存储器类: 与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity.Fragment 或 Servi

  • Android Jetpack组件库LiveData源码深入探究

    目录 前言 一.LiveData 二.使用案例 三.LiveData 实现原理 四.LiveData 相关源码 五.LiveData分发问题 Android Jetpack之ViewModel.LiveData Android Jetpack之LifeCycle Android Jetpack之DataBinding+ViewModel+LiveData+Room 前言 Jetpack是一个由多个技术库组成的套件,可帮助开发者遵循最佳做法,减少样板代码并编写可在各种Android版本和设备中一致

  • Android Jetpack组件支持库DataBinding与ViewModel与LiveData及Room详解

    目录 一.官方推荐的Jetpack架构 二.添加依赖 三.创建Repository 四.创建ViewModel 五.activity中使用 Android Jetpack之ViewModel.LiveData Android Jetpack之LifeCycle 一.官方推荐的Jetpack架构 ViewModel是介于View(视图)和Model(数据模型)之间的中间层,能够使视图和数据分离,又能提供视图和数据之间的通信. LiveData是一个能够在ViewModel中数据发生变化时通知页面刷

  • 详解Android JetPack之LiveData的工作原理

    前言 本篇文章主要讲解LiveData工作的原理,如果还不知道LiveData如何用的话,请参考官方文档. LiveData的讲解涉及到了Lifecycle的知识,如果你还不了解LifeCycle,请参考文档LifeCycle介绍. 介绍 LiveData是一个数据持有类,它可以通过添加观察者被其他组件观察其变更.不同于普通的观察者,它最重要的特性就是遵从应用程序的生命周期,如在Activity中如果数据更新了但Activity已经是destroy状态,LivaeData就不会通知Activit

  • Android Jetpack组件中LifeCycle作用详细介绍

    目录 Jetpack 1.那么Jetpack是什么呢 2.为何使用Jetpack 3.Jetpack与AndroidX LifeCycle 1.LifeCycle的作用 2.LifeCycle应用 1.设计组件 2.使用组件 3.总结LifeCycle的使用 Jetpack Jetpack,我觉得翻译为“飞行器”更好听,因为Google针对编程历史乱象,整理出一套组件库,帮助开发者创造更完美的应用作品.现在市面上,很多公司招聘面试要求渐渐把Jetpack看作必会技能,Google也在疯狂的安利J

  • Android JetPack组件的支持库Databinding详解

    目录 简介 启用databinding 布局xml variable (变量标签) data (数据标签) @{}表达式 绑定普通数据 绑定可观察数据 对单个变量的绑定-fields 对集合的绑定-collections 绑定对象-objects 绑定LiveData 双向绑定 简介 DataBinding 是 Google 在 Jetpack 中推出的一款数据绑定的支持库,利用该库可以实现在页面组件中直接绑定应用程序的数据源.使其维护起来更加方便,架构更明确简介. DataBinding 唯一

  • Android Jetpack组件Navigation导航组件的基本使用

    目录 1.Navigation 基本概念 2.Navigation 使用入门 2.1 添加Navigation依赖 2.2 创建导航图 2.3 导航图中添加目的地Fragment 2.4 Activity添加 NavHost 2.5 LoginFragment 代码编写 2.6 welcomeFragment 代码编写 总结 本篇主要介绍一下 Android Jetpack 组件 Navigation 导航组件的 基本使用 当看到 Navigation单词的时候 应该就大概知道 这是一个关于导航

  • Android Jetpack架构中ViewModel接口暴露的不合理探究

    目录 暴露 Mutable 状态 暴露 Suspend 方法 在 Jetpack 架构规范中, ViewModel 与 View 之间应该遵循单向数据流的通信方式,Events 永远从 View 流向 VM ,而 State 从 VM 流向 View. 如果 ViewModel 对 View 暴露了不适当的接口类型,则会破坏单向数据流的形成.不适当的接口类型常见于以下两点: 暴露 Mutable 状态 暴露 Suspend 方法 暴露 Mutable 状态 ViewModel 对外暴露的数据状态

  • Android Jetpack组件ViewModel基本用法详解

    目录 引言 一.概述与作用 二.基本用法 小结 引言 天道好轮回,终于星期五,但是还是忙碌了一天.在项目中,我遇到了一个问题,起因则是无法实时去获取信息来更新UI界面,因为我需要知道我是否获取到了实时信息,我想到的办法有三,利用Handler收发消息在子线程与主线程切换从而更新信息,其二则是利用在页面重绘的时候(一般是页面变动如跳转下个页面和将应用切至后台),其三就是利用Jetpack中最重要的组件之一ViewModel,最后我还是选择了ViewModel,因为感觉更方便. 其实想到的前面两个方

  • Android Jetpack组件DataBinding详解

    目录 Android之DataBinding DataBinding DataBinding的优势 亮点 使用DataBinding 单向绑定数据 双向绑定 Android之DataBinding DataBinding 数据绑定 DataBinding的优势 代码更加简洁,可读性会更高.部分和UI控件有关的代码可以在布局文件当中完成. 不需要使用findViewById()方法. 布局文件可以完成简单的业务逻辑处理. 亮点 开发中不需要持有控件的引用 拥有双向绑定的特性 数据与UI同步 使用D

随机推荐