view层操纵用户接口,仅仅有必要的功能暴露给其他层,以便调用。
5.Presenter层
NotesPresenter类是Presenter的特征 ,它实现了接口NotesContract.UserActionsListener
public class NotesPresenter implements NotesContract.UserActionsListener {
看这个 NotesContract.UserActionListener接口,它描述了来自view的入口动作,例如查看或增加一个便笺。view不应该直接操纵用户接口,它影响着model。取而代之的是它应该和presenter进行交互。
interface UserActionsListener {
void loadNotes(boolean forceUpdate);
void addNewNote();
void openNoteDetails(@NonNull Note requestedNote);
}
6.连接view和presenter层
下面让我看一下,view 和 presenter层在实际开发中是怎样交互的。在这个步骤中我们不增加任何新的代码。我们仅仅来探究这个应用是怎样架构的。
在Android Studio工具中打开NotesFragment类(app/src/main/java/.../notes/NotesFragment.java)。
// private NotesContract.UserActionsListener mActionsListener;
现在我们注释掉
mActionsListener属性,它会展示给我们在那调用了这个属性以及怎样调用presenter中方法。
例如,当我们单击悬浮按钮时会触发“add note”UI经由这个presenter(mActionsListener.addNewNote()):
// Set up floating action button
FloatingActionButton fab = ...
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mActionsListener.addNewNote();
}
});
这是当我们单击悬浮按钮时,要求presenter显示一个指定的便笺
NoteItemListener mItemListener = new NoteItemListener() {
@Override
public void onNoteClick(Note clickedNote) {
mActionsListener.openNoteDetails(clickedNote);
}
};
现在,增加一个
mActionsListener回调,我们需要它来运行我们的app
private NotesContract.UserActionsListener mActionsListener;
7.创建NotesPresenter
接下来让我们看一下怎样在onCreate()方法中创建NotesPresenter对象
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mListAdapter = new NotesAdapter(new ArrayList<Note>(0), mItemListener);
mActionsListener = new NotesPresenter(Injection.provideNotesRepository(), this); }
我们将会使用Injection类取出一个NotesRepository的实例。在稍后测试期间,它很容易转化出一个实现类——在我们的测试中简单的注入一个不同的服务层,也许在预定义的方法中仅仅模拟部分功能。
轻量级类注入使构建更具味道
为了测试,注入stub和mocked类到其他的组件中以便模拟和测试功能是必不可少的。例如在稍后我们的测试中,我们将会在便笺库中重写一些功能来模拟保存和加载便笺数据。这个Injection类会返回便笺库的实例。
在源码中我们有两个实现类:
- 在prod特色中,它会返回一个模拟网络延迟时间的实现类。请查看类NotesServiceApiImpl.java
- 在mock特色中,它会返回一个服务层的实现类和返回仿造的甚至可以在测试过程中配置的数据集。请查看类FakeNotesServiceApiImpl.java
8.运行我们的app
打开构建变体窗口并选择 prodDebug 变体。(低版本Android Studio 是在左侧)
连接物理设备或模拟器然后依次选择 “Run-->Run app” 来启动我们的app:
当出现选择一个目标设备对话框时,选择一个设备并勾选“将来使用同样的设备启动app”,然后单击“ok”按钮。
我们应该看到一个空白页面,有一个悬浮按钮(但没有监听事件)和一个左侧滑动的导航抽屉:
注意:此时的app仅是一个骨架,大多数UI功能还没有具体实现。