Android mvp 官方实例解析

一 官方文档说明

概要

这个例子是很多实例变化的基础(后续还有一些实例 ),是mvp模式的简单实现,它采用依赖注入的方式为用户提供本地和远程数据源的存储库,用回调的方式进行异步任务的处理。

Android mvp 官方实例解析_第1张图片

mvp 概要图片

注意:在mvp结构中,view 被重载

  • android.view.VIew 类将会被当作 “android view”
  • view 接收来自解析器(presenter)的指令,被简称为 “view”

Fragments

使用 fragments的两个原因

  • 把Activity和fragment 分离 是非常适合实现mvp的,Activity 完全控制和连接view 和 presenters.
  • 使用fragment 有利于平板或者多分辨率

概念

四个功能

  • Tasks
  • TaskDetails
  • AddEditTask
  • Statistics

每个功能都有

  • 在view 和presenter之间都定义好了协议

  • Activity负责创建fragment和presenters

  • fragment 实现view 的接口

  • presenter 实现 presenter接口

    一般来说,业务逻辑执行在presenter中,view 用来执行android 的ui工作
    view 大多数情况没有业务逻辑,它主要将presenter的命令转为ui操作,并监听用户的操作传递给presenter.
    规范接口 用于定义连接 view和presenters。

程序运行

如图所示 先就增加一个任务的操作进行代码分享

Android mvp 官方实例解析_第2张图片
![Screenshot_2016-09-13-14-24-04.png](http://upload-images.jianshu.io/upload_images/1658181-63c8ee941b591d13.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

代码分析

AddEditTaskActiviy (增加任务的activity)

@Override
protected void onCreate(Bundle savedInstanceState) {    
  super.onCreate(savedInstanceState);    
setContentView(R.layout.addtask_act);  、
 // Set up the toolbar.  设置标题
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);   
setSupportActionBar(toolbar);   
ActionBar actionBar = getSupportActionBar(); 
actionBar.setDisplayHomeAsUpEnabled(true);  
actionBar.setDisplayShowHomeEnabled(true);  
// 1.创建fragment  
AddEditTaskFragment addEditTaskFragment = (AddEditTaskFragment)   
getSupportFragmentManager().findFragmentById(R.id.contentFrame);    
String taskId = null;   
if (addEditTaskFragment == null) {       
addEditTaskFragment = AddEditTaskFragment.newInstance();      
if (getIntent().hasExtra(AddEditTaskFragment.ARGUMENT_EDIT_TASK_ID)) {     
taskId = getIntent().getStringExtra(AddEditTaskFragment.ARGUMENT_EDIT_TASK_ID);          
actionBar.setTitle(R.string.edit_task);
Bundle bundle = new Bundle();   
bundle.putString(AddEditTaskFragment.ARGUMENT_EDIT_TASK_ID, taskId);       
addEditTaskFragment.setArguments(bundle); 
   } else {            actionBar.setTitle(R.string.add_task);        }   
 ActivityUtils.addFragmentToActivity(getSupportFragmentManager(),      
  addEditTaskFragment, R.id.contentFrame);    }  
 // Create the presenter    2.创建 presenter 
new   AddEditTaskPresenter( taskId,  Injection.provideTasksRepository(getApplicationContext()),          
addEditTaskFragment);}

结合文档和代码,再activity的oncreate方法中,主要两个操作

  • 创建fragment
  • 实例化 presenter

AddEditTaskFragment (View) 代码

@Override
public void onActivityCreated(Bundle savedInstanceState) { 
super.onActivityCreated(savedInstanceState);   
FloatingActionButton fab =            (FloatingActionButton) getActivity().findViewById(R.id.fab_edit_task_done); 
fab.setImageResource(R.drawable.ic_done); 
fab.setOnClickListener(new View.OnClickListener() { 
   @Override
    public void onClick(View v) {
        mPresenter.saveTask(mTitle.getText().toString(), mDescription.getText().toString()); 
   }
});
}

在 onActivityCreate中 实现了完成增加任务的按钮,把用户的操作传递给presenter

AddEditTaskFragment 实现了AddEditTaskContract.view接口

AddEditTaskContract 代码

public interface AddEditTaskContract {
interface View extends BaseView {
    void showEmptyTaskError();
    void showTasksList();
    void setTitle(String title);
    void setDescription(String description);
    boolean isActive();
}
interface Presenter extends BasePresenter {
    void saveTask(String title, String description);
    void populateTask();
}
}

这个就是文档中说的 contract 协议 定义了view 的接口,供view去实现里面的方法,定义了presenter接口供对应的presenter去实现。

BaseView 基view 因为所有的view都要关联一个presenter

 public interface BaseView {
void setPresenter(T presenter);
}

看完View层 ,再看P层

AddEditTaskPresenter (P 层代码)

实现了 AddEditTaskContract.Presenter接口
构造方法

//三个参数  任务 id,数据源,关联的view
public AddEditTaskPresenter(@Nullable String taskId, @NonNull TasksDataSource     
tasksRepository,   
@NonNull AddEditTaskContract.View addTaskView) {
 mTaskId = taskId;
mTasksRepository = checkNotNull(tasksRepository);
mAddTaskView = checkNotNull(addTaskView);
//view 设置 presenter
mAddTaskView.setPresenter(this);

}

接下来看AddEditTaskFragment 中完成按钮的点击事件

 mPresenter.saveTask(mTitle.getText().toString(), mDescription.getText().toString());

也就是present的saveTask方法

@Override 
public void saveTask(String title, String description) {
 if (isNewTask()) {
    createTask(title, description);
} else {
    updateTask(title, description);
}}

直接看 createTask方法

private void createTask(String title, String description) {
//新建一个任务
Task newTask = new Task(title, description);
if (newTask.isEmpty()) {
    mAddTaskView.showEmptyTaskError();
} else {
    //保存数据
    mTasksRepository.saveTask(newTask);
   //通知view 层展示新的数据 (前面文档:view层通过接收present的指令)
    mAddTaskView.showTasksList();
}}

AddEditTaskPresenter 还实现了 TasksDataSource.GetTaskCallback

TasksDataSource(M 层)

数据层的两个方法

@Override
public void onTaskLoaded(Task task) {
// The view may not be able to handle UI updates anymore
if (mAddTaskView.isActive()) {
    mAddTaskView.setTitle(task.getTitle());            
    mAddTaskView.setDescription(task.getDescription());
  }}
@Override
public void onDataNotAvailable() {
// The view may not be able to handle UI updates anymore
if (mAddTaskView.isActive()) {
    mAddTaskView.showEmptyTaskError();
}}

获取数据的接口

/**
 * Main entry point for accessing tasks data.
 * 

* For simplicity, only getTasks() and getTask() have callbacks. Consider adding callbacks to other * methods to inform the user of network/database errors or successful operations. * For example, when a new task is created, it's synchronously stored in cache but usually every * operation on database or network should be executed in a different thread. */ public interface TasksDataSource { interface LoadTasksCallback { void onTasksLoaded(List tasks); void onDataNotAvailable(); } interface GetTaskCallback { void onTaskLoaded(Task task); void onDataNotAvailable(); } void getTasks(@NonNull LoadTasksCallback callback); void getTask(@NonNull String taskId, @NonNull GetTaskCallback callback); void saveTask(@NonNull Task task); void completeTask(@NonNull Task task); void completeTask(@NonNull String taskId); void activateTask(@NonNull Task task); void activateTask(@NonNull String taskId); void clearCompletedTasks(); void refreshTasks(); void deleteAllTasks(); void deleteTask(@NonNull String taskId);}

MVP的好处

  • 分离了视图和业务逻辑,降低耦合
  • 简化了Activity 的代码

你可能感兴趣的:(Android mvp 官方实例解析)