标签: android-mvvm

将LiveData与数据绑定结合使用

随着Android体系结构组件的稳定,我开始将所有基本ViewModel的更新到新的实现ViewModel.根据我的理解,LiveData建议使用它来保存Model类,因为它更好地处理生命周期.

我喜欢使用Data Binding它,因为它使代码在Java/Kotlin方面更清晰,并且不需要"观察"值更改来更新UI.但是,Data Binding如果Model(或ViewModel)扩展BaseObservable,LiveData则仅使用监视数据的布局会发生变化.我理解的主要目标之一LiveData是以编程方式观察和更新UI,但对于简单的更新,Data Binding非常有用.

这个问题已经报道过(GitHubStack Overflow),并且首先说版本1.0会有它,现在据说这个功能正在开发中.

为了同时使用LiveDataData Binding,我创建了一个非常简单的类实现,它扩展了BaseObservable:

import android.arch.lifecycle.LiveData
import android.arch.lifecycle.MutableLiveData
import android.databinding.BaseObservable

class ObservableMutableLiveData<T>() : BaseObservable() {

    private var data: MutableLiveData<T> = MutableLiveData()

    constructor(data: T) : this() {
        this.data.value = data
    }

    public fun set(value: T) {
        if (value != data.value) {
            data.value = value …
Run Code Online (Sandbox Code Playgroud)

android kotlin android-databinding android-mvvm android-architecture-components

22
推荐指数
2
解决办法
1万
查看次数

无法解析片段中的 ViewModelProvider 构造?

我花了很多时间试图弄清楚为什么在下面的代码中(接近结尾),我在 ViewModelProvider(this) 上遇到错误。我也试过 getActivity() 而不是 'this',同样的问题。我得到的错误是“无法解析构造函数......”


import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;



public class ItemSetupFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_setup, container, false);

        return view;
    }

    @Override
    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        ItemSetupFragmentModel model = new ViewModelProvider(this).get(ItemSetupFragmentModel.class);
        model.getKids().observe(this, users -> {
            // update UI
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

显示 Android Studio 中编译错误的图像

android android-mvvm android-livedata android-architecture-components

15
推荐指数
2
解决办法
1万
查看次数

接收流的Android单元测试视图模型

我有一个 ViewModel 与用例对话并返回一个流,即Flow<MyResult>. 我想对我的 ViewModel 进行单元测试。我是使用流程的新手。需要帮助请。这是下面的视图模型 -

class MyViewModel(private val handle: SavedStateHandle, private val useCase: MyUseCase) : ViewModel() {

        private val viewState = MyViewState()

        fun onOptionsSelected() =
            useCase.getListOfChocolates(MyAction.GetChocolateList).map {
                when (it) {
                    is MyResult.Loading -> viewState.copy(loading = true)
                    is MyResult.ChocolateList -> viewState.copy(loading = false, data = it.choclateList)
                    is MyResult.Error -> viewState.copy(loading = false, error = "Error")
                }
            }.asLiveData(Dispatchers.Default + viewModelScope.coroutineContext)
Run Code Online (Sandbox Code Playgroud)

MyViewState 看起来像这样 -

 data class MyViewState(
        val loading: Boolean = false,
        val data: List<ChocolateModel> = emptyList(),
        val error: …
Run Code Online (Sandbox Code Playgroud)

android junit4 kotlin android-mvvm kotlin-coroutines

15
推荐指数
1
解决办法
7702
查看次数

使用onSaveInstanceState()和ViewModel保存活动的状态

阅读本文后,我得到了一些关于ViewModels的问题:

https://developer.android.com/topic/libraries/architecture/saving-states

它在这里说你应该结合使用a来ViewModel进行配置更改(比如屏幕旋转),并使用onSaveInstanceState()所有其他情况来销毁活动,然后重新创建以保存UI状态.

我的问题是我们如何知道onCreate(Bundle)调用时恢复状态的方法- 我应该使用ViewModel还是应该使用收到的包作为参数?当配置发生变化时,onSaveInstanceState()也会调用,显然onCreate()总是被调用.

如果我只从ViewModel恢复状态,它将不会始终保留正确的数据(因为活动可能由于配置更改之外的其他原因而被破坏).如果我只使用我保存的包onSaveInstanceState()那么为什么我会用a ViewModel开头?

android persistence android-activity android-mvvm android-viewmodel

12
推荐指数
1
解决办法
1341
查看次数

如果快速调用,android LiveData Observable不会返回数据

处理需要一次性向同一端点发送多个API调用的应用程序.

例如 - 目录浏览方案,需要通过发送当前文件夹中所有文件夹的get调用来获取目录结构.问题是,响应正确地为所有文件夹提供了响应,但LiveData observable只为整个列表提供了一个响应.

目录结构: -

test -> temp -> temp1 -> temp2 
                      -> temp3
                      -> temp4
Run Code Online (Sandbox Code Playgroud)

可观察到收听回调: -

mViewModel.getServerFilesLiveData().observe(this, browseServerDataResource -> {
      if (browseServerDataResource != null) {
        if (browseServerDataResource.status == APIClientStatus.Status.SUCCESS) {
          if (browseServerDataResource.data != null) {
            Timber.i("Got data for path %s in Observable", browseServerDataResource.data.path);
            if (browseServerDataResource.data.folderList != null
              && browseServerDataResource.data.folderList.size() > 0) {
              for (final String name : browseServerDataResource.data.folderList) {
                final ServerDirectoryPathInfo pathInfo = new ServerDirectoryPathInfo();
                pathInfo.completePath = browseServerDataResource.data.path + "/" + name;
                getFolderDownloadPath(pathInfo.completePath);
              }
            }
            mFolderCountToParse--; …
Run Code Online (Sandbox Code Playgroud)

android retrofit2 android-mvvm android-livedata

11
推荐指数
1
解决办法
881
查看次数

为什么必须删除作为observeForever 添加到LiveData 的观察者?

我在Android LiveData 文档中阅读了以下内容

您可以使用 observeForever(Observer) 方法注册一个没有关联 LifecycleOwner 对象的观察者。在这种情况下,观察者被视为始终处于活动状态,因此始终会收到有关修改的通知。您可以调用 removeObserver(Observer) 方法删除这些观察者。

我正在使用 MVVM 架构模式构建一个应用程序,使用ViewModel并在我的 ViewModel 类中声明 LiveDatas。在我的 viewModel 中,我将 aobserveForever设置为 LiveData:

val password by lazy {
    MutableLiveData<String>()
}

init {
    initObservable()
}

private fun initObservable() {
    password.observeForever {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

根据我从文档中的理解,每次实例化 ViewModel 的视图(使用前面的代码)被销毁时,我都应该删除观察者,对吗?但是一旦视图被销毁,观察者不应该被销毁(因为 ViewModel 实例在视图中被实例化并且也会被销毁)?

android android-mvvm android-livedata android-viewmodel

11
推荐指数
1
解决办法
7726
查看次数

Handle Toolbar back button with Navigation component

I'm following single activity approach. I have navigation toolbar, whenever i go to other screens (fragments) instead of hamburger icon i will have back arrow.

What i want to achieve is, pop my current fragment using action on pressing toolbar back arrow.

I've tried

requireActivity().getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
    @Override
    public void handleOnBackPressed() {
        NavHostFragment.findNavController(EventDetailsFragment.this)
        .navigate(R.id.action_nav_event_details_to_nav_home);
    }
});
Run Code Online (Sandbox Code Playgroud)

But not getting the call over there, i checked by running app in debug mode.

android android-toolbar android-mvvm android-navigation-graph

11
推荐指数
2
解决办法
7780
查看次数

MVVM 中存储库级别或 Activity 内的 Android 权限?

我正在使用 MVVM clean 架构,需要使用融合位置提供程序获取当前位置,因此在获取当前位置之前,我需要检查用户是否已授予访问位置和互联网的权限。
我正在通过实现数据源从存储库检索位置,但我不确定应该在哪里请求许可。在存储库中,当我请求位置或在活动中时,首先请求许可,然后请求位置?

在第一种情况下,流程将是:
1)User clicks the button(view)
2)Viewmodel requests for location (viewmodel->usecase->repository)
3)Repository checks permissions and requests location
4)Observable is returned which emits location(s) or error if no permission were granted (or other error)

第二种情况:
1)User clicks the button and permission are checked/requested inside activity
2)If permission are granted, viewmodel requests position otherwise view shows an error
3)Repository requests and returns the location

第一种方法对我来说看起来更简单、更符合逻辑。表示层只是请求位置,然后存储库返回位置或错误,但是数据层内的逻辑可能太多了?

android mvvm android-permissions android-mvvm

9
推荐指数
1
解决办法
3096
查看次数

使用导航组件多次触发 LiveData 观察者

场景:我有两个名为FirstFragment和 的片段UnitFragment。我从FirstFragmentUnitFragment选择一个单元返回FirstFragmet使用navController.popBackStack();并将单元数据发送到FirstFragment观察单元数据的单元。

这是我onViewCreatedFirstFragment

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    if (viewModel == null) { // Lazy Initialization
        ApiService apiService = ApiServiceProvider.getInstance();
        AddNewWareViewModelFactory addNewWareViewModelFactory = new AddNewWareViewModelFactory(apiService);
        viewModel = new ViewModelProvider(this, addNewWareViewModelFactory).get(AddWareViewModel.class);
    }

    Log.i(TAG, "OnViewCreated -----> Called");
    viewModel.callNewWare(parentCode);
    viewModel.getNewWareResponse().observe(getViewLifecycleOwner(),
            resObject -> Log.i(TAG, "API Response LiveData Count -----> " + count++)); // Started From Zero

    NavHostFragment navHostFragment = …
Run Code Online (Sandbox Code Playgroud)

java android android-mvvm android-livedata android-architecture-navigation

9
推荐指数
1
解决办法
576
查看次数

使用 Hilt 进行依赖注入时,android compose 项目中的共享视图模型?

任何人都知道如何在不同的可组合项之间保留共享视图模型对象?我正在使用 hilt 并在可组合项中使用 hilt 注入视图模型实例。基本上有 3 个屏幕共享相同的数据和更改,我想共享它,并且我正在考虑通过共享视图模型共享这些数据。

myViewModel: MyViewModel = hiltViewModel()
Run Code Online (Sandbox Code Playgroud)

那么我如何使用这个 MyViewModel 作为共享视图模型?

viewmodel android-mvvm android-jetpack-compose

9
推荐指数
2
解决办法
5013
查看次数