查询资料的其中一个场景:
创建一个回调函数,当查询后台的时候,后台有结果了,回调对应的回调函数,并将结果保存到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. centos7_Lnmp编译安装

    17年面试运维岗位的时候,面试官要求输出一份lnmp编译的操作文档,于是有了如下安装nginx+php+mysql,进入正题: 准备环境 环境:centos7.3 软件:nginx-1.12.1 + ...

  2. mysql之力扣数据库题目620有趣的电影优化记录

    闲着没事儿刷刷力扣的数据库题目,题目编号620:有趣的电影,下面是题目描述: 优化前的sql及执行时间: 优化后的sql及执行时间: 这里对筛选条件进行了优化: 1.select * 的查找效率要比逐 ...

  3. 本地打包编译jdk版本问题

    一.遇到的问题 进行项目接入pinpoint-ice插件,启动项目时pinpoint-agent日志报如下不支持jdk8的错误.'   二.排查 我们是在个人笔记本电脑上windows环境下通过mav ...

  4. IBM jca 工具的学习与整理

    IBM jca 工具的学习与整理 背景 发现自己最早看到IBM这个工具的时间是 2022年9月份. 但是一直没有进行过仔细的学习与论证. 本周出现了一个问题. 虽然通过gclog明显看出来是一个oom ...

  5. [转帖]如何使用 minio 进行 BR 备份

    https://tidb.net/blog/ada69456#5.%20%E4%BD%BF%E7%94%A8%20minio%20%E8%BF%9B%E8%A1%8C%20BR%20%E5%A4%87 ...

  6. [转帖]linux服务之tuned

    https://www.cnblogs.com/createyuan/p/5701650.html RHEL/CentOS 在 6.3 版本以后引入了一套新的系统调优工具 tuned/tuned-ad ...

  7. 【转帖】ARM 虚拟化技术简介

    一. 虚拟化技术二. 虚拟化技术的比较2.1 全虚拟化和二进制重写(Pure virtualization and binary rewriting)2.2 半虚拟化( Para-virtualiza ...

  8. [转帖]Elasticsearch 的 30 个调优最佳实践!

    Elasticsearch 的 30 个调优最佳实践! https://zhuanlan.zhihu.com/p/406264041 ES 发布时带有的默认值,可为 es 的开箱即用带来很好的体验.全 ...

  9. Oracle PDB的相关使用说明

    Oracle PDB的相关使用说明 摘要 PDB pluggable database 是Oracle12c以上的版本(Oracle18c.oracle19c) 新增加的一个特性. 他可以实现灵活插拔 ...

  10. Linux查找当前目录下包含部分内容的文件,并且copy到指定路径的简单方法

    1 获取文件列表 find . -name "*.data" |xargs grep -i 'yearvariable' | uniq | awk '{print $1}' |cu ...