android-fragments 如何在Android中使用MVVM调用API

ruoxqz4g  于 2022-11-13  发布在  Android
关注(0)|答案(1)|浏览(153)

我想从服务器调用一些API,为此我使用了改型
我为我的项目选择了MVVM架构,我有2个片段
片段A和片段B。

**片段A:**调用API并在RecyclerView中显示列表。
**片段B:**是详细信息页,显示数据信息。

当从设备/仿真器(在片段B中)点击后退按钮时,以及当显示片段B时,再次调用API!
我想当使用viewmodel时,APIS只是第一次调用!
我只想第一次调用API!

存储库类:

class FragmentARepository @Inject constructor(private val api: ApiServices) {

    suspend fun dataList(): Flow<MyResponse<ResponseDataList>> {
        return flow {
            emit(MyResponse.loading())
            emit(MyResponse.success(api.dataList().body()))
        }.catch { emit(MyResponse.error(it.message.toString())) }.flowOn(Dispatchers.Main)
    }
}

视图模型类:

@HiltViewModel
class FragmentAViewModel @Inject constructor(private val repository: FragmentARepository) : ViewModel() {

    val dalaListLive = MutableLiveData<List<ResponseDataList.Meal>>()
    fun loadDataList() = viewModelScope.launch(Dispatchers.IO) {
        repository.dataList().collect { dataList.postValue(it.body()?.meals!!) }
    }
}

片段A类:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        //InitViews
        binding?.apply {
            viewModel.loadDataList()
            viewModel.dataList.observe(viewLifecycleOwner) {
                dataAdapter.setData(it.data.meals)
                                dataRv.setupRecyclerView(
                                    LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false),
                                    dataAdapter
                                )
                }
            }
}

为什么我的API每次都调用?我只想调用一次。
"我只想要一次"

vcirk6k6

vcirk6k61#

你的假设是错误的。ViewModels并不是“调用API一次”。只要你请求它们,它们就会调用API。在你的FragmentA中,你从onViewCreated请求视图模型中的数据,当你重新进入这个片段时(例如,当从FragmentB点击 back 时),它就会执行。
但是,ViewModel是创建的并且是持久的(直到某个点):https://developer.android.com/topic/libraries/architecture/viewmodel
因此,如果您希望API调用只发生一次,则可以在ViewModel的init中调用它:

@HiltViewModel
class FragmentAViewModel @Inject constructor(private val repository: FragmentARepository) : ViewModel() {

    val dalaListLive = MutableLiveData<List<ResponseDataList.Meal>>()

    init {
        viewModelScope.launch(Dispatchers.IO) {
        repository.dataList().collect {
            dataList.postValue(it.body()?.meals!!) 
        }
    }
}

在您的FragmentA中,只需观察 dalaListLive

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        //InitViews
        binding?.apply {
            viewModel.dataList.observe(viewLifecycleOwner) {
                dataAdapter.setData(it.data.meals)
                                dataRv.setupRecyclerView(
                                    LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false),
                                    dataAdapter
                                )
                }
            }
}

相关问题