
Model View Presenter
Google命名項目為:Android框架藍圖
TODO-MVP

基類:
BasePresenter BaseView分別為所有的presenter 和 view的基類
BasePresenter中含有方法start(),該方法的作用是開始獲取數據并調用view中的方法來改變界面顯示,其調用時機是在Fragment中的onResume()中
public interface BasePresenter{
void start();
}
BseView中含有方法setPresenter 該方法的作用是將presenter實例傳入View中,該方法的調用是在presenter的實現類的構造函數中。
public interface BaseView<T>{
void setPresenter(T presenter);
}
契約類
契約類用來統一管理所有presenter,view的接口,這種方式使得presenter,view有哪些功能一目了然
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();
}}
activity在項目中是一個全局的控制者,負責創建view以及presenter實例,將兩者聯系起來,
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);}
創建后的fragment實例作為presenter的構造函數參數被傳入,這樣就可以在presenter中調用view中的方法了。
實例中我們將fragment作為view層的實現類,為什么是fragment?
- 我們把activity作為一個全局控制類來創建對象,把fragment作為view
- 因為fragment比較靈活,能夠方便的處理邊界適配的問題
public class TaskDetailFragment extends Fragment implements TaskDetailContract.View {
@Override
public void onResume() {
super.onResume();
mPresenter.start();
}
@Override
public void setPresenter(@NonNull TaskDetailContract.Presenter presenter) {
mPresenter = checkNotNull(presenter);
}
}
上面可以看到setPresenter()方法,該方法繼承父類,通過該方法,view獲得了presenter實例,從而可以調用presenter代碼來處理業務邏輯,onResume中還調用了presenter的start()方法。
public class TaskDetailPresenter implements TaskDetailContract.Presenter {
private final TasksRepository mTasksRepository;
private final TaskDetailContract.View mTaskDetailView;
@Nullable
private String mTaskId;
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();
}
presenter構造函數中調用了view的setPresenter方法將自身實例傳入,start方法用來處理了數據加載與展示,如果界面需要做出相應的變化,直接調用view層的方法即可,這樣view層與presenter層就能夠很好的劃分
最后還剩下model層實現,項目中model層最大的特點是被賦予了數據獲取的職責,與我們平常model層只定義實體對象截然不同,實例中,數據的獲取、存儲、數據狀態變化都是model層的任務,presenter會根據需要調用該層的數據處理邏輯并在需要時將回調傳入。這樣model、presenter、view都只處理各自的任務,此種實現確實是單一職責最好的詮釋。