Google官方MVP脑补
Posted 劲火星空
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Google官方MVP脑补相关的知识,希望对你有一定的参考价值。
一、组成
下面一张图胜过千言万语
用一句话来概括,就说P将M和V分开了,其实也没这么简单,P会将自己传递给V,然后在V中进行一些逻辑
二、分析
如下是Google官方基础MVP程序的框架
我们发现在主包下面有6个子包和两个接口
- addedittask:添加修改界面
- data:数据源
- statistics:统计界面
- taskdetail:Todo item 详情页见面
- tasks:Todo 事件列表界面(主界面)
- util:帮助工具类
- BasePresenter、BaseView:presenter、view接口基类
我们发现关键概念里面讲的4个属性就是这里面的4个子包,并且这4个子包有很大的相似性,它们都有下面4个接口或者类
- Contract
- Activity
- Fragment
- Presenter
三、代码
下面以taskdetail为例子来进行代码的分析
(1)TaskDetailContract
这是一个合同类,其中包含了两个接口,一个是View,一个是presenter。这些接口中的方法在具体的类中会实现并可以调用
public interface TaskDetailContract
interface View extends BaseView<Presenter>
void setLoadingIndicator(boolean active);
void showMissingTask();
void hideTitle();
void showTitle(String title);
void hideDescription();
void showDescription(String description);
void showCompletionStatus(boolean complete);
void showEditTask(String taskId);
void showTaskDeleted();
void showTaskMarkedComplete();
void showTaskMarkedActive();
boolean isActive();
interface Presenter extends BasePresenter
void editTask();
void deleteTask();
void completeTask();
void activateTask();
(2)TaskDetailActivity
可以看到在Activity中主要实现了两大功能,一个是Fragment也就是View的初始化,另一个就是Presenter的初始化,在Presenter的初始化过程中需要传入两个参数,一个是View,一个是数据库操作类,这同时也说明了Presenter对V和M的连通行。
public class TaskDetailActivity extends AppCompatActivity
public static final String EXTRA_TASK_ID = "TASK_ID";
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.taskdetail_act);
// Set up the toolbar.
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar ab = getSupportActionBar();
ab.setDisplayHomeAsUpEnabled(true);
ab.setDisplayShowHomeEnabled(true);
// Get the requested task id
String taskId = getIntent().getStringExtra(EXTRA_TASK_ID);
TaskDetailFragment taskDetailFragment = (TaskDetailFragment) getSupportFragmentManager()
.findFragmentById(R.id.contentFrame);
if (taskDetailFragment == null)
taskDetailFragment = TaskDetailFragment.newInstance(taskId);
ActivityUtils.addFragmentToActivity(getSupportFragmentManager(),
taskDetailFragment, R.id.contentFrame);
// Create the presenter
new TaskDetailPresenter(
taskId,
Injection.provideTasksRepository(getApplicationContext()),
taskDetailFragment);
@Override
public boolean onSupportNavigateUp()
onBackPressed();
return true;
(3)TaskDetailPersenter
终于到了Persenter了,这个家伙的逻辑应该是很复杂吧,毕竟要实现M和V的桥梁作用,但是这里只是实现来一些方法,这些方法是用来操作数据库和View的,其中数据库和View的具体实现方法还是由其自己来实现。
因此这里的逻辑并不复杂,最关键的一个地方就是通过mTaskDetailView.setPresenter(this)方法将自己传递到View中
这里的mTaskDetailView是通过参数传递进来的,代码太多了,所以精简一下
public class TaskDetailPresenter implements TaskDetailContract.Presenter
public TaskDetailPresenter(@Nullable String taskId,
@NonNull TasksRepository tasksRepository,
@NonNull TaskDetailContract.View taskDetailView)
mTaskId = taskId;
mTasksRepository = checkNotNull(tasksRepository, "tasksRepository cannot be null!");
mTaskDetailView = checkNotNull(taskDetailView, "taskDetailView cannot be null!");
mTaskDetailView.setPresenter(this);
@Override
public void start()
openTask();
private void openTask()
@Override
public void editTask()
if (Strings.isNullOrEmpty(mTaskId))
mTaskDetailView.showMissingTask();
return;
mTaskDetailView.showEditTask(mTaskId);
@Override
public void deleteTask()
if (Strings.isNullOrEmpty(mTaskId))
mTaskDetailView.showMissingTask();
return;
mTasksRepository.deleteTask(mTaskId);
mTaskDetailView.showTaskDeleted();
@Override
public void completeTask()
@Override
public void activateTask()
private void showTask(@NonNull Task task)
(4)TaskDetailFragment
我们在Fragment中获得了Presenter的对象,这样可以就可以调用Presenter的方法,然后通过Persenter来调用M和V的方法,这样就可以实现用P来控制M和V了。
以下是部分程序:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
View root = inflater.inflate(R.layout.taskdetail_frag, container, false);
setHasOptionsMenu(true);
mDetailTitle = (TextView) root.findViewById(R.id.task_detail_title);
mDetailDescription = (TextView) root.findViewById(R.id.task_detail_description);
mDetailCompleteStatus = (CheckBox) root.findViewById(R.id.task_detail_complete);
// Set up floating action button
FloatingActionButton fab =
(FloatingActionButton) getActivity().findViewById(R.id.fab_edit_task);
fab.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
mPresenter.editTask();
);
return root;
@Override
public void setPresenter(@NonNull TaskDetailContract.Presenter presenter)
mPresenter = checkNotNull(presenter);
尊重作者,尊重原创,参考文章
http://www.jianshu.com/p/569ab68da482
http://www.jianshu.com/p/2ecfc1f4561d
以上是关于Google官方MVP脑补的主要内容,如果未能解决你的问题,请参考以下文章