You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将LiveData<ApiResponse<Contacts>>转换为LiveData<ApiResponse<List<Contact>>>

解决LiveData<ApiResponse>到LiveData<ApiResponse<List>>的转换问题

要完成这个转换,核心是利用Android架构组件中的Transformations.map()方法——它可以监听原LiveData的变化,将每个发射的值转换为你需要的类型,同时完整保留ApiResponse的状态(加载、成功、错误),不会丢失任何状态信息。

核心思路

我们需要对原LiveData中的每个ApiResponse<Contacts>做针对性转换:

  • 当状态为成功时,提取Contacts中的items列表,包装成ApiResponse.Success<List<Contact>>
  • 当状态为错误/加载时,直接复用原状态的信息,确保UI能正确接收状态通知(比如加载转圈、错误提示)

代码实现(Java版本)

假设你的ApiResponse是一个封装了状态的类(比如包含Success、Error、Loading三种状态),代码如下:

import androidx.lifecycle.LiveData;
import androidx.lifecycle.Transformations;

protected LiveData<ApiResponse<List<Contact>>> createCall() {
    LiveData<ApiResponse<Contacts>> contactsLiveData = apiService.getContacts();
    
    return Transformations.map(contactsLiveData, apiResponse -> {
        // 处理成功状态:提取items列表,同时做非空兜底
        if (apiResponse instanceof ApiResponse.Success) {
            Contacts contacts = ((ApiResponse.Success<Contacts>) apiResponse).getData();
            List<Contact> contactList = contacts.getItems() != null ? contacts.getItems() : new ArrayList<>();
            return new ApiResponse.Success<>(contactList);
        }
        // 处理错误状态:保留原错误信息(如果有错误码等字段也要一并传递)
        else if (apiResponse instanceof ApiResponse.Error) {
            String errorMessage = ((ApiResponse.Error<Contacts>) apiResponse).getMessage();
            return new ApiResponse.Error<>(errorMessage);
        }
        // 处理加载状态:直接返回加载实例
        else if (apiResponse instanceof ApiResponse.Loading) {
            return ApiResponse.Loading.getInstance();
        }
        // 兜底处理其他未知状态
        else {
            return apiResponse;
        }
    });
}

代码实现(Kotlin版本)

如果用Kotlin,借助密封类的when表达式,代码会更简洁:

import androidx.lifecycle.LiveData
import androidx.lifecycle.Transformations

override fun createCall(): LiveData<ApiResponse<List<Contact>>> {
    val contactsLiveData = apiService.getContacts()
    
    return Transformations.map(contactsLiveData) { response ->
        when (response) {
            is ApiResponse.Success -> {
                // 非空兜底,避免items为null
                val contactList = response.data.items ?: emptyList()
                ApiResponse.Success(contactList)
            }
            is ApiResponse.Error -> ApiResponse.Error(response.message, response.errorCode) // 传递所有错误信息
            ApiResponse.Loading -> ApiResponse.Loading
        }
    }
}

关键注意事项

  • 状态完整性:一定要处理ApiResponse的所有状态,不能只处理成功状态,否则UI会丢失加载中、错误等关键状态的通知。
  • 非空安全:Contacts中的items可能为null,务必做非空判断,避免后续业务逻辑出现空指针异常。
  • 字段传递:如果你的ApiResponse包含额外字段(比如错误码、请求ID),转换时要把这些字段一并复制到新的ApiResponse对象中,保证信息不丢失。

内容的提问来源于stack exchange,提问作者maxxxo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:09:59