[译]Android架构组件 – 查看ViewModel – 第二部分
2017-06-12 20:33
656 查看
原文链接:https://riggaroo.co.za/android-architecture-components-looking-viewmodels-part-2/
如果你回忆上一篇文章,下图指出了我们将如何组织我们的“日期倒计时”应用。
本文我们将创建上图显示的
因为
如果
创建名为
现在在
包含
事件数据现在从
创建一个Dagger组件
创建自定义
删除
在Fragment中,我们使用委托给ViewModel的删除方法:
对于
Android架构组件文档
日期倒计时应用-完整代码
Dagger2 测试实例
如果你回忆上一篇文章,下图指出了我们将如何组织我们的“日期倒计时”应用。
本文我们将创建上图显示的
EventListViewModel和
AddEventViewModel。可在这篇文章找到所有源码。在开始创建
ViewModels之前,我们需要首先看看什么是
ViewModel。
什么是ViewModel?
ViewModel既不是新的概念,也不是Android的概念。 名
ViewModel来自于2005年左右的Microsoft设计的MVVM模式。新的架构组件中,一个新类是
ViewModel类。
ViewModel负责为
View准备数据。它们将数据暴露给正在监听更改的任何视图。在Android中,使用
ViewModel类时应该记住一些具体的事实:
ViewModel可以在Activity配置更改中保留其状态。它保存的数据立即可用于下一个Activity实例,而不需要在
onSaveInstanceState()中保存数据,并手动还原。
ViewModel与特定的Activity或Fragment实例无关。
ViewModel允许在Fragment之间轻松共享数据(意味着您不再需要通过ctivity来协调动作)。
ViewModel将保持在内存中,直到
Lifecycle的范围永远消失 - Activity调用finish; 在Fragment调用ditached。
因为
ViewModel独立于Activity或Fragment实例,它不直接引用其中的任何View或保持上下文的引用。真会导致内存泄漏。
如果
ViewModel需要应用的上下文(例如查找系统服务),它可继承
AndroidViewModel类,并有一个构造函数来接收Application实例。
创建ViewModel
EventListViewModel
EventListViewModel类用于打开日期倒计时应用打开时展示事件列表。
创建名为
EventListViewModel的类。确保它从架构组件类继承
ViewModel。类中,我们打算将之前放在
EventListFragment中的代码迁移到
ViewModel中。
EventListViewModel中添加
LiveData变量。EventRepository变量使用Dagger注入。
EventListViewModel现在长这样:
public class EventListViewModel extends ViewModel implements CountdownComponent.Injectable { private LiveData<List<Event>> events = new MutableLiveData<>(); @Inject EventRepository eventRepository; @Override public void inject(CountdownComponent countdownComponent) { countdownComponent.inject(this); events = eventRepository.getEvents(); } public LiveData<List<Event>> getEvents() { return events; } }
现在在
EventListFragment中,我们打算使用
ViewModel替换事件加载代码:
public class EventListFragment extends LifecycleFragment { private EventListViewModel eventListViewModel; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { //.. inflate view etc eventListViewModel = ViewModelProviders.of(this, new CountdownFactory(countdownApplication).get(EventListViewModel.class); eventListViewModel.getEvents().observe(this, events -> { adapter.setItems(events); }); return v; } }
包含
ViewModelProvider.of(..)的行将创建一个新的
EventListViewModel类(如果不存在),或者它将获取存在于定义的作用域(在这种情况下是
EventListFragment)的类。这是神奇的地方。当设备旋转并且Fragment被重新创建时,将在此处返回的
ViewModel是之前使用的。这允许我们保留屏幕的状态,而无需手动将信息保存到
Bundle并自己恢复。
事件数据现在从
EventListViewModel获取。如前所述,通过将其作为第一个参数,
LiveDataobservable将自动为您管理。这意味着当Fragment不再使用时,Fragment将会处理可观察物。如果Fragment未启动或恢复,则不可调用observable回调。
创建一个Dagger组件
CountdownComponent。我们将使用它来注入
ViewModel的依赖。
@Singleton @Component(modules = {CountdownModule.class}) public interface CountdownComponent { void inject(EventListViewModel eventListViewModel); void inject(AddEventViewModel addEventViewModel); interface Injectable { void inject(CountdownComponent countdownComponent); } }
创建自定义
ViewModelProvider.NewInstanceFactory用于实例化
ViewModel。当
ViewModelProvider需要创建新的
ViewModel实例,它将调用工厂类的
create方法。
public class CountdownFactory extends ViewModelProvider.NewInstanceFactory { private CountdownApplication application; public CountdownFactory(CountdownApplication application) { this.application = application; } @Override public <T extends ViewModel> T create(Class<T> modelClass) { T t = super.create(modelClass); if (t instanceof CountdownComponent.Injectable) { ((CountdownComponent.Injectable) t).inject(application.getCountDownComponent()); } return t; } }
删除
Event,可以在
ViewModel中添加一个方法。该方法委托
EventRepository删除事件。本例中,使用Rxjava来代理后台线程。
public class EventListViewModel extends ViewModel implements CountdownComponent.Injectable { //.. public void deleteEvent(Event event) { eventRepository.deleteEvent(event) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new CompletableObserver() { @Override public void onSubscribe(Disposable d) { } @Override public void onComplete() { Timber.d("onComplete - deleted event"); } @Override public void onError(Throwable e) { Timber.e("OnError - deleted event: ", e); } }); } }
在Fragment中,我们使用委托给ViewModel的删除方法:
View.OnClickListener deleteClickListener = v -> { Event event = (Event) v.getTag(); eventListViewModel.deleteEvent(event); };
对于
AddEventViewModel的实现,查看完整代码示例。
总结
新的Android架构组件解决了我们以前无法处理的常见情况。现在通过使用ViewModel和
ViewModelProvider来处理屏幕旋转非常简单。
参考
ViewModel文档Android架构组件文档
日期倒计时应用-完整代码
Dagger2 测试实例
相关文章推荐
- Android架构组件之ViewModel
- Android官方架构组件介绍之ViewModel
- [置顶] Android架构组件ViewModel和LiveData介绍及使用
- Android架构组件三 Android Architecture Components ViewModel组件解析
- 改造 Android 官方架构组件 ViewModel
- [译]Android架构组件 - 查看Lifecycles - 第三部分
- 架构组件之 ViewModel | 中文教学视频
- Android Architecture Components应用架构组件源码详解(基于1.0以上)(第二篇ViewModel和LiveData)
- [译]Android架构组件 – 查看Room和LiveData – 第一部分
- android使用ViewPager组件实现app引导查看页面
- 【框架篇】mvc、mvp、mvvm使用关系总结 原创 2016年03月27日 10:04:21 标签:android /架构 9837 MVC MVC全名是Model View Controller,
- Android使用原生组件WebView加载网页和数据的方法
- Qt学习之路(38): model-view架构
- 自定义Android组件之带图像的TextView(转)
- 新书内容连载(1):自定义Android组件之带图像的TextView
- Android 组件系列(1):自动完成输入内容的组件(AutoCompleteTextView )
- Android自定义View设定到FrameLayout布局中实现多组件显示
- 我谈Silverlight架构和模式运用1-- ModelView模式最简单教程-讲解无代码触发事件,以及类型转换器的强大功能
- 一种新的基于Windows Mobile平台的移动开发N层架构(第二部分)
- NET初学者架构设计指南(四)Model-View-Controller