Transform LiveData

来源:https://www.cnblogs.com/ttylinux/archive/2023/07/15/17556654.html
-Advertisement-
Play Games

原文地址:https://blog.csdn.net/zhanglei5415/article/details/131434931 ## 一、問題 當對含有中文的url字元串,進行NSURL對象包裝時,是不能被識別的。 不會得到期望的NSURL對象,而是返回一個nil 值 ; ```objectiv ...


查詢資料的其中一個場景: 創建一個回調函數,當查詢後臺的時候,後臺有結果了,回調對應的回調函數,並將結果保存到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
});

 

 

 

 

 

版權聲明: 作者:ttylinux     出處:http://www.cnblogs.com/ttylinux/     本文版權歸作者,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 學習`pandas`的過程中,為了嘗試`pandas`提供的各類功能強大的函數,常常需要花費很多時間去創造測試數據。 在`pandas`中,快速創建測試數據可以更快的評估 `pandas` 函數。通過生成一組測試數據,可以評估例如 `read_csv`、`read_excel`、`groupby`等 ...
  • 學習數字信號處理演算法時整理的學習筆記。本篇介紹 ISB 獨立邊帶調幅信號的調製與解調,內附全套 MATLAB 代碼。 ...
  • **WPF 實現 Message 消息提醒控制項** > 控 件:Message > > 作 者:WPFDevelopersOrg - **驚鏵** > >[原文鏈接](https://github.com/WPFDevelopersOrg/WPFDevelopers "原文鏈接"):https:// ...
  • 作用 程式設計過程中,我們經常需要增加一些動態效果,以此改善用戶的使用體驗。本文將介紹一種方法,動態顯示按鈕狀態,使其得到滑鼠焦點後自動放大,失去滑鼠焦點後自動縮小。 效果圖 先放一張原圖(滑鼠還未移動到按鈕上): 獲得滑鼠焦點的Button按鈕:(這裡因為是圖片,放大不明顯,所以筆者將按鈕字體也一 ...
  • **背景** 前段時間小編開發了一個控制台程式,把資料庫中的數據取出來按照編碼名稱分別存儲文件,存儲文件之前檢查是否存在當前文件,如果存在刪除。開始小批量的數據還挺順利的,當批量執行問題就來了,每次執行到一半時,創建的文件不增加反而變少了,經過日誌捕捉才發現是欄位里包含特殊符號惹的禍。小編是按照欄位 ...
  • TreeView無法綁定SelectedItem,而又想知道treeview的selecteditem的變化,當然目前有很多方法,我這裡簡單的提供一個。 目前主要思路就是通過處理xaml的TreeViewItem的IsSelected屬性來進行綁定。 <TreeView BorderThicknes ...
  • 因為筆者有著大量運維部署站點的需求,所以之前一直在陸陸續續學習並實踐各種`Linux`的`Shell`命令,在此記錄一些高頻命令的使用的說明,方便自己回顧加深記憶 ...
  • 本文主要介紹常用的存儲類型及它們之間的對比差異,輔助幫助大家在不同需求和場景下選擇合適的存儲類型。 近期,AIGC、GPT大模型、數據中台等熱點話題備受關註,那麼具體在不同的行業場景下,如何選擇對應的存儲介質呢?選型的時候該考慮哪些因素呢? 通過本文主要介紹常用的存儲類型及它們之間的對比差異,輔助幫 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...