Mvp-googlesamples/android-architecture

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都只處理各自的任務,此種實現確實是單一職責最好的詮釋。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容