查询资料的其中一个场景:
创建一个回调函数,当查询后台的时候,后台有结果了,回调对应的回调函数,并将结果保存到LiveData中。
public class DataModel {
    ...
    public MutableLiveData<List<Repo>> searchRepo(String query) {
        final MutableLiveData<List<Repo>> repos = new MutableLiveData<>();
        githubService.searchRepos(query)
                .enqueue(new Callback<RepoSearchResponse>() {
                    @Override
                    public void onResponse(@NonNull Call<RepoSearchResponse> call, @NonNull Response<RepoSearchResponse> response) {
                        repos.setValue(response.body().getItems());
                    }
                    ...
                });
        return repos;
    }
}
如果 RepoViewModel的部分写成这样:
public class RepoViewModel extends ViewModel {
    ...
    MutableLiveData<List<Repo>> searchRepo(String query) {
        // NO!
        return dataModel.searchRepo(query);
    }
}
这种写法有如下两个问题:
1.当输入新的关键字的时候,DataModel会返回新的LiveData,这样View每次都要去observe新的LiveData
2.当View重新创建的时候,会再次调用searchRepo,于是DataModel又再一次查询,并且返回新的LiveData。
为了避免重复创建LiveData,只使用固定的一个LiveData,可以使用 Transformations改造上述代码:
下述代码repos返回的都是同一个LiveData。Transformations不会使返回的LiveData变成新的对象,因此View一值都是对LiveData做observe的。即解决了上面提到的两个问题。
public class RepoViewModel extends ViewModel {
...
    private final MutableLiveData<String> query = new MutableLiveData<>();
    private final LiveData<List<Repo>> repos;     public RepoViewModel(final DataModel dataModel) {
        ...
        repos = Transformations.switchMap(query, new Function<String, LiveData<List<Repo>>>() {
            @Override
            public LiveData<List<Repo>> apply(String userInput) {
                return dataModel.searchRepo(userInput);
            }
        });
    }
    ...
    void searchRepo(String userInput) {
        query.setValue(userInput);
    }
}
如果dataModel查询结果可能为null,也就是没有返回值,但是依然需要返回一个backing LiveData,那么,可以使用 AbsentLiveData
/**
* A LiveData class that has {@code null} value.
*/
public class AbsentLiveData extends LiveData {
    private AbsentLiveData() {
        postValue(null);
    }
    public static <T> LiveData<T> create() {
        //noinspection unchecked
        return new AbsentLiveData();
    }
}
repos = Transformations.switchMap(query, new Function<String, LiveData<List<Repo>>>() {
    @Override
    public LiveData<List<Repo>> apply(String userInput) {
        if (TextUtils.isEmpty(userInput)) {
            return AbsentLiveData.create();
        } else {
            return dataModel.searchRepo(userInput);
        }
    }
});
LiveData<Y> switchMap (LiveData<X> trigger,Function<X, LiveData<Y>> func)
Creates a LiveData, let's name it swLiveData, which follows next flow: it reacts on changes of trigger LiveData, applies the given function to new value of trigger LiveData and sets resulting LiveData as a "backing" LiveData to swLiveData. "Backing" LiveData means, that all events emitted by it will retransmitted by swLiveData.
If the given function returns null, then swLiveData is not "backed" by any other LiveData.
The given function func will be executed on the main thread.
创建一个swLiveData,每当triggerLiveData的值发生变化的时候,就使用triggerLiveData的值,应用相应的函数操作,得到的结果,作为swLiveData的值。
 
Consider the case where you have a LiveData containing a user id. Every time there's a new user id emitted, you want to trigger a request to get the user object corresponding to that id, from a repository that also returns a LiveData.
The userIdLiveData is the trigger and the LiveData returned by the repository.getUserById is the "backing" LiveData.
In a scenario where the repository contains User(1, "Jane") and User(2, "John"), when the userIdLiveData value is set to "1", the switchMap will call getUser(1), that will return a LiveData containing the value User(1, "Jane"). So now, the userLiveData will emit User(1, "Jane"). When the user in the repository gets updated to User(1, "Sarah"), the userLiveData gets automatically notified and will emit User(1, "Sarah").
When the setUserId method is called with userId = "2", the value of the userIdLiveData changes and automatically triggers a request for getting the user with id "2" from the repository. So, the userLiveData emits User(2, "John"). The LiveData returned by repository.getUserById(1) is removed as a source.
MutableLiveData userIdLiveData = ...;
LiveData userLiveData = Transformations.switchMap(userIdLiveData, id ->
     repository.getUserById(id)); void setUserId(String userId) {
      this.userIdLiveData.setValue(userId);
}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

LiveData<Y> map (LiveData<X> source, Function<X, Y> func)
 
Applies the given function on the main thread to each value emitted by source LiveData and returns LiveData, which emits resulting values.
The given function func will be executed on the main thread.
Suppose that you have a LiveData, named userLiveData, that contains user data and you need to display the user name, created by concatenating the first and the last name of the user. You can define a function that handles the name creation, that will be applied to every value emitted by useLiveData.
在主线程上,对源source liveData的每个数值应用函数操作func,返回的一个新的LiveData,包含func操作的结果,比如如下例子代码,
userLiveData作为源,要创建一个新的LiveData,它的每个值是firstname与lastname的合并。
LiveData userLiveData = ...;
LiveData userName = Transformations.map(userLiveData, user -> {
      return user.firstName + " " + user.lastName
});

Transform LiveData的更多相关文章

  1. CSS3 3D立方体效果-transform也不过如此

    CSS3系列已经学习了一段时间了,第一篇文章写了一些css3的奇技淫巧,原文戳这里,还获得了较多网友的支持,在此谢过各位,你们的支持是我写文章最大的动力^_^. 那么这一篇文章呢,主要是通过一个3D立 ...

  2. 深入node之Transform

    Transform流特性 在开发中直接接触Transform流的情况不是很多,往往是使用相对成熟的模块或者封装的API来完成流的处理,最为特殊的莫过于through2模块和gulp流操作.那么,Tra ...

  3. CSS 3 学习——transform 3D转换渲染

    以下内容根据官方规范翻译,没有翻译关于SVG变换的内容和关于矩阵计算的内容. 一般情况下,元素在一个无景深无立体感的平面(flat plane)上渲染,这个平面就是其包含块所处的平面.同时,页面上的其 ...

  4. CSS 3学习——transform 2D转换

    首先声明一点,transform属性不为none的元素是它的定位子元素(绝对定位和固定定位)的包含块,而且对内创建一个新的层叠上下文. 注意:可以通过 transform-box 属性指定元素的那个盒 ...

  5. Hilbert-Huang Transform(希尔伯特-黄变换)

    在我们正式开始讲解Hilbert-Huang Transform之前,不妨先来了解一下这一伟大算法的两位发明人和这一算法的应用领域 Section I 人物简介 希尔伯特:公认的数学界“无冕之王”,1 ...

  6. 【CSS3动画】transform对文字及图片的旋转、缩放、倾斜和移动

    前言:之前我有写过CSS3的transform这一这特性,对于它的用法,还不是很透彻,今天补充补充,呵呵 你懂的,小司机准备开车了. a)再提一提transform的四个属性 ①旋转--->ro ...

  7. CSS3和javascript中的transform

    在javascript中,WebkitTransform 大概相当于 transform .transform 为标准,WebkitTransform 适用于Webkit浏览器.js中的WebkitT ...

  8. CALayer的transform属性

    先来与View比较一下 View:transform -> CGAffineTransformRotate... layer:transform -> CATransform3DRotat ...

  9. rxjs5.X系列 —— transform系列 api 笔记

    欢迎指导与讨论:) 前言 本文是笔者翻译 RxJS 5.X 官网各类operation操作系列的的第一篇 -- transform转换.如有错漏,希望大家指出提醒O(∩_∩)O.更详细的资料尽在rxj ...

  10. NDT(Normal Distribution Transform) 算法(与ICP对比)和一些常见配准算法

    原文地址:http://ghx0x0.github.io/2014/12/30/NDT-match/ By GH 发表于 12月 30 2014 目前三维配准中用的较多的是ICP迭代算法,需要提供一个 ...

随机推荐

  1. SD协议-基本概念

    1.SD协议版本 SD 1.1 SD 2.0 SD 3.0 在看协议的时候,需要注意协议的版本,注意版本之间的差别 SD协议是常见的数据通信和存储卡之间的协议 HDMI是显示相关的协议,遵循HDMI协 ...

  2. WebApi使用Swagger

    services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API ...

  3. 2.4G+MCU低功耗二合一芯片SI24R03

    2.4G+MCU低功耗二合一芯片SI24R03 1 简介 Si24R03 是一款高度集成的低功耗 SOC 芯片,其集成了基于 RISC-V 核的低功耗 MCU 和 工作在 2.4GHz ISM 频段的 ...

  4. [转帖]Centos使用chrony做时间同步

    https://www.cnblogs.com/lizhaoxian/p/11260041.html Chrony是一个开源的自由软件,在RHEL 7操作系统,已经是默认服务,默认配置文件在 /etc ...

  5. [转帖]PostgreSQL中的schema和user

    https://www.cnblogs.com/abclife/p/13905336.html postgresql中,用户创建的所有对象都被创建在指定的schema(或namespace)中.其他用 ...

  6. [转帖]全球CPU市场格局(2022)

    https://www.eet-china.com/mp/a222817.html 本文选自"2022年国产服务器CPU研究框架",重点分析2022年CPU产业链.CPU市场规模. ...

  7. Linux查看登录用户记录信息

    Linux查看登录用户记录信息 登录成功的信息 last 可以简单统计一下: last |awk '{print $3}' |sort |uniq -c |sort -k1nr 登录失败的 就是 la ...

  8. 我们开源了一个轻量的 Web IDE UI 框架

    我们开源了一个轻量的 Web IDE UI 框架 Molecule 一个轻量的 Web IDE UI 框架 简介 Molecule 是一个受 VS Code 启发,使用 React.js 构建的 We ...

  9. 基于Spring Cache实现Caffeine、jimDB多级缓存实战

    作者: 京东零售 王震 背景 在早期参与涅槃氛围标签中台项目中,前台要求接口性能999要求50ms以下,通过设计Caffeine.ehcache堆外缓存.jimDB三级缓存,利用内存.堆外.jimDB ...

  10. MySQL新增数据,修改数据,删除数据

    连接本地mysql语句 mysql -hlocalhost -uroot -proot DML-介绍 DML英文全称是:用来对数据库中表的数据记录进行 增 删 改 操作. 增加使用 insert 删除 ...