-1

使用 ViewModel 时,View 会观察 ViewModel。它必须注册为观察者。在 Google 的官方教程中,此注册被委托给对象的observe()方法LiveData

public class MyViewModel extends ViewModel {
    private MutableLiveData<List<User>> users;
    public LiveData<List<User>> getUsers() {
        if (users == null) {
            users = new MutableLiveData<List<Users>>();
            loadUsers();
        }
        return users;
    }

    private void loadUsers() {
        // Do an asynchronous operation to fetch users.
    }
}

public class MyActivity extends AppCompatActivity {
    public void onCreate(Bundle savedInstanceState) {
        // Create a ViewModel the first time the system calls an activity's onCreate() method.
        // Re-created activities receive the same MyViewModel instance created by the first activity.

        MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
        model.getUsers().observe(this, users -> {
            // update UI
        });
    }
}

该方法getUsers()返回LiveData对象本身。它的observe()方法用于注册观察者。视图不观察ViewModel它的实现,但它的一部分。

现在这是最佳实践,当使用对象时ViewModels不是观察自己而是观察它们的部分实现LiveData?或者这是低质量的介绍?

4

2 回答 2

0

根据克里斯的回答,我给出了自己的答案。我认为本教程不是最佳实践,原因很简单,一个对象不应该暴露它的内部实现。根据 Chris 的论证,我正在寻找一种在不丢失命名特性的情况下进行封装的选项。结果是内部observerUsers()委托给LiveData对象的方法。

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        MainActivityViewModel model = ViewModelProviders.of(this).get(MainActivityViewModel.class);
        model.observeUsers(this,
                new Observer<List<User>>() {
                    @Override
                    public void onChanged(@Nullable List<User> users) {
                        updateUI();
                    }
                }
        );
    }

    void updateUI() {

    }

    static class MainActivityViewModel extends ViewModel {
        private MutableLiveData<List<User>> users;

        public void observeUsers(@NonNull LifecycleOwner owner,
                                 @NonNull Observer<List<User>> observer) {
            getUsers().observe(owner, observer);
        }

        private LiveData<List<User>> getUsers() {
            if (users == null) {
                users = new MutableLiveData<>();
                loadUsers();
            }
            return users;
        }

        private void loadUsers() {
            // Do an asynchronous operation to fetch users.
        }
    }

    static class User {
    }

}

仍然List<User>公开内部实现。它可以改进为一个类Users

我将所有内容放入一个文件并使用内部静态类。这并不意味着最佳实践。只是为了能够快速编辑一个文件中的所有内容。特别是模型User属于它自己的文件,而我经常像这样把它ViewModel放到View它所属的类中。

我的第二点批评者与ViewModel自身观察底层模型的情况相匹配。在这种情况下,观察者方法onChange()非常通用,需要一个非常通用的更新方法,例如updateUI(). 您可能希望观察模型的更具体事件以进行具体更新。

于 2018-03-28T10:41:08.967 回答
0

我会说是的,ViewModel 通过某种形式的 Observable 公开其数据是最佳实践,无论是 LiveData 还是类似于 RX Observable 的东西。

这与其他架构(例如 MVP)有所不同,在 MVP 中,演示者通常会引用视图,当某些事情发生变化时会调用该视图。该指南对 ViewModel 应该引用的内容非常具体。

A ViewModel must never reference a view, Lifecycle, or any class that may hold a reference to the activity context.

通过 ViewModel 将数据公开为 Observable,这意味着视图可以来去去去,一旦订阅,将收到最新数据和任何后续更新。再次,指南有一些细节。

If the activity is re-created, it receives the same MyViewModel instance that was created by the first activity. When the owner activity is finished, the framework calls the ViewModel objects's onCleared() method so that it can clean up resources

https://developer.android.com/topic/libraries/architecture/viewmodel.html

于 2018-03-27T15:58:05.377 回答