美文网首页
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 官方实例解析

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