如何在没有ViewModelProviders类的情况下获取ViewModel?

6

针对之前的问题如何获取ViewModel以及我找到的示例,它并没有解决我的问题。由于我没有权限在那里发表评论,因此我必须再次提问。我没有ViewModelProviders类,我想使用所有示例和文档中找到的“of”方法。

model = ViewModelProviders.of(this).get(Something.class);

在Android Studio中,我找不到“android.arch.lifecycle:extensions”供我添加依赖项。当我搜索时,它显示“没有内容可显示”。我的API版本是27。 因此,为了使用非废弃元素,在Fragment中我有以下代码:
public class EventDetailsFragment extends Fragment
{
EventViewModel viewModel;

@Override
public void onActivityCreated (Bundle savedInstanceState)
{
    super.onActivityCreated(savedInstanceState);
    ViewModelProvider.Factory factory = ViewModelProvider.AndroidViewModelFactory.getInstance(getActivity().getApplication());
    // HERE IS THE ISSUE: Seems not good practice to have to create a new ViewModelProvider every time this Fragment is created. 
    // Perhaps I should just create a singleton ViewModelProvider in the Activity or Application, 
    // so here could call getActivity().getViewModelProvider(this, factory).
    ViewModelProvider viewModelProvider = new ViewModelProvider(this, factory);
    viewModel = viewModelProvider.get(EventViewModel.class);
...
}

我应该做什么?


你所发布的代码恰好就是ViewModelProviders.of()所执行的代码 - 它会在每次调用时创建一个新的ViewModelProvider类。 - ianhanniballake
有趣。看起来效率不高。你觉得我使用单例模式的想法怎么样? - ozzylee
1
ViewModelProvider只是ViewModelStoreFactory的一个薄包装器,因此将其作为Activity/Fragment的成员变量(它不能是单例,因为它引用了ViewModelStoreOwner即Activity/Fragment)肯定很方便,但这不会改变您的应用程序的工作/性能。 - ianhanniballake
2个回答

8

打开app/build.gradle文件,找到dependencies块,并手动将生命周期依赖项添加到列表中:

dependencies {
    implementation 'android.arch.lifecycle:extensions:1.1.1'

    // ... 
}

同步项目后,您应该能够获得ViewModel的实例。


谢谢。对于简单的问题,简单的解决方案是我喜欢的。 - ozzylee

1

如果您对Android和Java有更好的了解,尝试学习一些MVVM架构。将此代码放入一些baseFragment方法中,然后进行:

abstract class BaseFragment extends Fragment() {
    //kotlin
    fun <T : ViewModel?> getViewModel(activity: FragmentActivity, modelClass: Class<T>): T {
        return ViewModelProviders.of(this, ViewModelFactory(activity)).get(modelClass)
    }

    //bytecode to java is this :/
    public final ViewModel obtainViewModel(@NotNull FragmentActivity activity, @NotNull Class modelClass) {
          return ViewModelProviders.of((Fragment)this, (Factory)(new 
          ViewModelFactory((Activity)activity))).get(modelClass);
       }
}

同时不要将此代码放入onViewCreated而不是onActivityCreated

// kotlin
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    viewModel = obtainViewModel(requireActivity(), KebabFragmentViewModel::class.java)
}

// java bytecode
public void onViewCreated(@NotNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    this.viewModel = (RollerFragmentViewModel)this.obtainViewModel(getFragmentActivity(), RollerFragmentViewModel.class); 
}

现在您需要观察者来观察来自viewModel的内容。可以在onViewCreated中使用,也许是为了一些可能需要较长时间的网络操作或其他操作。

// kotlin
viewModel.list.observe(this, Observer { list ->
    list?.let {
        viewModel.myKebabAdapter.updateList(list)
    }
})

//java
this.viewModel.getErrorMessage().observe((LifecycleOwner)this, (Observer)(new Observer() {
    ...
    public final void onChanged(@Nullable List list) {
        this.viewModel.myKebabAdapter.updateKebabList(list)
    }
}

在viewModel中,您可以观察到我们可爱的变量,以在activity/fragment上使用。

// kotlin
var list: MutableLiveData<MutableList<User>> = MutableLiveData()

// java variable and getter
@NotNull
private MutableLiveData userList;

@NotNull
public final MutableLiveData getUserList() {
   return this.userList;
}

现在您需要在dependencies{}块中添加app/build.gradle依赖项。
//lifecycle
implementation "android.arch.lifecycle:extensions:1.1.1"
implementation "android.arch.lifecycle:viewmodel:1.1.1"

// RxJava
implementation "io.reactivex.rxjava2:rxkotlin:2.2.0"
implementation "io.reactivex.rxjava2:rxandroid:2.0.0"
implementation "io.reactivex.rxjava2:rxjava:2.1.10"

寻找一些关于如何正确进行编程的博客教程。我个人不太喜欢https://developer.android.com/,因为它曾经很难跟进。可以试试 Medium。

祝好运。Java 代码大多数都是反编译的,希望能正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接