美文网首页
Android mvp 官方实例解析

Android mvp 官方实例解析

作者: 谢侃 | 来源:发表于2016-09-13 15:38 被阅读0次

一 官方文档说明

概要

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

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。

程序运行

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

![Screenshot_2016-09-13-14-24-04.png](https://img.haomeiwen.com/i1658181/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<Presenter> {
    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
<pre><code> public interface BaseView<T> {
void setPresenter(T presenter);
}
</pre></code>
看完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 中完成按钮的点击事件
<pre><code> mPresenter.saveTask(mTitle.getText().toString(), mDescription.getText().toString());
</pre></code>
也就是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.
 * <p> * 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<Task> 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 官方实例解析

    一 官方文档说明 概要 这个例子是很多实例变化的基础(后续还有一些实例 ),是mvp模式的简单实现,它采用依赖注入...

  • MVC和MVP

    Android mvp 架构的自述 如何更高效的使用MVP以及官方MVP架构解析 老的MVC架构 新的MVP架构 ...

  • 框架相关(MVP+Rxjava+Retrofit+OkHttp+

    Android官方MVP架构示例项目解析Retrofit 2.0 + OkHttp 3.0 配置 通过Loader...

  • Android官方架构项目之MVP + Loaders

    在上一篇 Android官方MVP架构项目解析 中我们分析了MVP架构的实现。主要是让Fragment作为View...

  • Android架构

    MVP+Retrofit+Rxjava在项目中实战解析 文章目标 MVP在android中的原理解析 MVP+Re...

  • MVP简单尝试

    MVP模式解析 标签: Android 架构 MVP MVP模式的核心思想 MVP将Activity中的U...

  • Android MVP探索

    googlesamples/android-architecture Android Google官方MVP架构分...

  • Android官方MVP架构项目解析

    前段时间Google在Github开源了一个项目Android Architecture Blueprints,在...

  • MVP+Retrofit+Rxjava在项目中实战解析 

    文章目标 MVP在android中的原理解析 MVP+Retrofit+Rxjava在项目中实战解析 架构经验分享...

  • MVP

    Google官方MVP+Dagger2架构详解【从零开始搭建android框架系列(6)】 Android MVP...

网友评论

      本文标题:Android mvp 官方实例解析

      本文链接:https://www.haomeiwen.com/subject/wrpmettx.html