【0188】再探MVP-1

本文分析的源码是开源项目实例,参考地址:https://github.com/antoniolg/androidmvpjava

1.传统的mvp架构实例1

以最熟悉的login登陆页面为例,目录结构以下:node

其中包含3个interface,3个实现,两两一组。android

1.1 View 部分

【LogView接口源码】git

 1 public interface LoginView {
 2     void showProgress();
 3 
 4     void hideProgress();
 5 
 6     void setUsernameError();
 7 
 8     void setPasswordError();
 9 
10     void navigateToHome();
11 }

【LoginActivity.java源码】github

 1 public class LoginActivity extends Activity implements LoginView, View.OnClickListener {
 2 
 3     private ProgressBar progressBar;
 4     private EditText username;
 5     private EditText password;
 6     private LoginPresenter presenter;  //持有presenter对象
 7 
 8     @Override protected void onCreate(Bundle savedInstanceState) {
 9         super.onCreate(savedInstanceState);
10         setContentView(R.layout.activity_login);
11 
12         progressBar = (ProgressBar) findViewById(R.id.progress);
13         username = (EditText) findViewById(R.id.username);
14         password = (EditText) findViewById(R.id.password);
15         findViewById(R.id.button).setOnClickListener(this);
16 
17         presenter = new LoginPresenterImpl(this,new LoginInteractorImpl()); //new一个代理对象:LoginPresenter
18     }
19 
20     @Override protected void onDestroy() {
21         presenter.onDestroy();
22         super.onDestroy();
23     }
24 
25     @Override public void showProgress() {
26         progressBar.setVisibility(View.VISIBLE);
27     }
28 
29     @Override public void hideProgress() {
30         progressBar.setVisibility(View.GONE);
31     }
32 
33     @Override public void setUsernameError() {
34         username.setError(getString(R.string.username_error));
35     }
36 
37     @Override public void setPasswordError() {
38         password.setError(getString(R.string.password_error));
39     }
40 
41     @Override public void navigateToHome() {
42         startActivity(new Intent(this, MainActivity.class));
43         finish();
44     }
45 
46     @Override public void onClick(View v) {
47         presenter.validateCredentials(username.getText().toString(), password.getText().toString());
48     }
49 }

【说明】网络

【1】实现了 LoginView 接口,架构

【2】持有presenter对象,而且new了一个presenter的实现类对象。ide

1 private LoginPresenter presenter;  //持有presenter对象
1 presenter = new LoginPresenterImpl(this,new LoginInteractorImpl()); //new一个代理对象:LoginPresenter

【3】在动做 触发的时候,调用了代理validateCredentials方法post

1 /**
2      * 触发调用代理的方法
3      * @param v
4      */
5     @Override public void onClick(View v) {
6  presenter.validateCredentials(username.getText().toString(), password.getText().toString());
7     }

一样在onDestroy()中引用了presenter代理实现的方法this

1 @Override protected void onDestroy() {
2  presenter.onDestroy();
3         super.onDestroy();
4     }

1.2 Presenter代理

【LoginPresenter源码】须要时两个被view调用的方法

1 public interface LoginPresenter {
2 
3     void validateCredentials(String username, String password);
4 
5     void onDestroy();
6 }

【LoginPresenterImpl】代理的实现类:

 1 public class LoginPresenterImpl implements LoginPresenter, LoginInteractor.OnLoginFinishedListener {
 2 
 3     private LoginView loginView; //持有view的对象
 4     private LoginInteractor loginInteractor;  //持有model对象
 5 
 6     public LoginPresenterImpl(LoginView loginView, LoginInteractor loginInteractor) {
 7         this.loginView = loginView; //在构造方法中将view传递进来
 8         this.loginInteractor = loginInteractor;  //在构造方法中将model传递进来
 9     }
10 
11     /**
12      * 在执行登陆验证的动做:
13      *  【1】触发view的动做
14      *  【2】将参数传递给model
15      * @param username
16      * @param password
17      */
18     @Override public void validateCredentials(String username, String password) {
19         if (loginView != null) {
20             loginView.showProgress();
21         }
22 
23         loginInteractor.login(username, password, this);
24     }
25 
26     @Override public void onDestroy() {
27         loginView = null;
28     }
29 
30     @Override public void onUsernameError() {
31         if (loginView != null) {
32             loginView.setUsernameError();
33             loginView.hideProgress();
34         }
35     }
36 
37     @Override public void onPasswordError() {
38         if (loginView != null) {
39             loginView.setPasswordError();
40             loginView.hideProgress();
41         }
42     }
43 
44     @Override public void onSuccess() {
45         if (loginView != null) {
46             loginView.navigateToHome();
47         }
48     }
49 }

【model接口】

 1 public interface LoginInteractor {
 2 
 3     interface OnLoginFinishedListener {  //被presenter实现的接口  4         void onUsernameError();
 5         void onPasswordError();
 6         void onSuccess();
 7     }
 8 
 9     void login(String username, String password, OnLoginFinishedListener listener);  
10 
11 }

【1】 Presenter代理实现类:实现了LoginPresenter,还实现了model接口的中的LoginInteractor.OnLoginFinishedListener接口。

【2】在代理类中持有了构造方法中直接传递进去了View和Model对象。

1     private LoginView loginView; //持有view的接口对象
2     private LoginInteractor loginInteractor;  //持有model接口对象
3 
4     public LoginPresenterImpl(LoginView loginView, LoginInteractor loginInteractor) {
5         this.loginView = loginView; //在构造方法中将view传递进来
6         this.loginInteractor = loginInteractor;  //在构造方法中将model传递进来
7     }

此处持有的是接口对象,在构造LoginPresenterImpl时,即在View中new代理类对象时:直接传递了本身自己和model实现类。对接口进行了转化,将接口对象转化为了实现类(注意)

1 presenter = new LoginPresenterImpl(this,new LoginInteractorImpl()); //new一个代理对象:LoginPresenter

【3】在动做执行时:直接调用了View的方法loginView.showProgress(),Model中对数据的传递和处理:loginInteractor.login(username, password, this)

 1 /**
 2      * 在执行登陆验证的动做:
 3      *  【1】触发view的动做
 4      *  【2】将参数传递给model
 5      * @param username
 6      * @param password
 7      */
 8     @Override public void validateCredentials(String username, String password) {
 9         if (loginView != null) {
10             loginView.showProgress();
11         }
12 
13         loginInteractor.login(username, password, this);  //此处只是将数据传递给了model最终的对数据的处理是在model中完成的
14     }

【4】model接口的中的LoginInteractor.OnLoginFinishedListener接口主要是对Login控制,Model不一样的处理的状态经过Model接口,在Presenter调用来更新View的界面显示。主要是对view的操做。

1    interface OnLoginFinishedListener {  //回调状态的更新View的UI显示
2 void onUsernameError(); 3 void onPasswordError(); 4 void onSuccess(); 5 }
 1 @Override public void onUsernameError() {
 2         if (loginView != null) {
 3             loginView.setUsernameError();
 4             loginView.hideProgress();
 5         }
 6     }
 7 
 8     @Override public void onPasswordError() {
 9         if (loginView != null) {
10             loginView.setPasswordError();
11             loginView.hideProgress();
12         }
13     }
14 
15     @Override public void onSuccess() {
16         if (loginView != null) {
17             loginView.navigateToHome();
18         }
19     }

1.3 Model 

【接口】包含两部分:①presenter实现的接口②Model 对数据处理的方法

 1 public interface LoginInteractor {
 2 
 3     interface OnLoginFinishedListener {  //被presenter实现的接口
 4         void onUsernameError();
 5         void onPasswordError();
 6         void onSuccess();
 7     }
 8 
 9     //对view传递的数据的处理,此处参数有presenter实现的接口对象 OnLoginFinishedListener
10     void login(String username, String password, OnLoginFinishedListener listener);
11 
12 }

【model实现】实现了LoginInteractor接口,只实现了login方法。

 1 public class LoginInteractorImpl implements LoginInteractor {
 2 
 3     @Override
 4     public void login(final String username, final String password, final OnLoginFinishedListener listener) {
 5         // Mock login. I'm creating a handler to delay the answer a couple of seconds
 6         new Handler().postDelayed(new Runnable() {
 7             @Override public void run() {
 8                 if (TextUtils.isEmpty(username)) {
 9                     listener.onUsernameError();
10                     return;
11                 }
12                 if (TextUtils.isEmpty(password)) {
13                     listener.onPasswordError();
14                     return;
15                 }
16                 listener.onSuccess();  //最终的数据处理这里作了临时的处理,调用listener的方法;实际项目会对作网络请求
17             }
18         }, 2000);
19     }
20 }
最终的数据处理这里作了临时的处理,调用LoginPresenterImpl中的onSuccess方法,是Model接口中的方法;实际项目会对作网络请求
1 @Override public void onSuccess() {
2         if (loginView != null) {
3             loginView.navigateToHome();
4         }
5   }

1.4 页面跳转的补充

【view接口中的定义】

 1 public interface LoginView {
 2     void showProgress(); 3 4 void hideProgress(); 5 6 void setUsernameError(); 7 8 void setPasswordError(); 9 10 void navigateToHome(); //view的页面的跳转 11 }
 1 public class LoginActivity extends Activity implements LoginView, View.OnClickListener {  2 
 3     private ProgressBar progressBar; 4 5  ...... 6 @Override public void navigateToHome() { 7 startActivity(new Intent(this, MainActivity.class));  //Activity的实现 跳转到MainAcitivity页面 8  finish(); 9  } 10 ......

【触发跳转】model的实现类进行了跳转页面的触发

 1 public class LoginInteractorImpl implements LoginInteractor {
 2 
 3  @Override 4 public void login(final String username, final String password, final OnLoginFinishedListener listener) { 5 // Mock login. I'm creating a handler to delay the answer a couple of seconds 6 new Handler().postDelayed(new Runnable() { 7 @Override public void run() { 8 if (TextUtils.isEmpty(username)) { 9  listener.onUsernameError(); 10 return; 11  } 12 if (TextUtils.isEmpty(password)) { 13  listener.onPasswordError(); 14 return; 15  } 16 listener.onSuccess(); //触发跳转 17  } 18 }, 2000); 19  } 20 }

【代理类作中介】

1 public class LoginPresenterImpl implements LoginPresenter, LoginInteractor.OnLoginFinishedListener {
2  ...... 3 @Override public void onSuccess() { 4 if (loginView != null) { 5  loginView.navigateToHome(); //跳转 6  } 7  } 8 ......

【总结】是一个反向的过程:model-->presenter-->view

调用过程总结以下:

1.5 总结

数据的传递过程:

【View发起】LoginActivity

1 /**
2      * 触发调用代理的方法
3      * @param v
4      */
5     @Override public void onClick(View v) {
6         presenter.validateCredentials(username.getText().toString(), password.getText().toString());
7     }

【Presenter传递】LoginPresenterImpl中调用model中的方法进行处理

 1 /**
 2      * 在执行登陆验证的动做:
 3      *  【1】触发view的动做
 4      *  【2】将参数传递给model
 5      * @param username
 6      * @param password
 7      */
 8     @Override public void validateCredentials(String username, String password) {
 9         if (loginView != null) {
10             loginView.showProgress();
11         }
12 
13         loginInteractor.login(username, password, this);
14     }

【Model的处理】LoginInteractorImpl 的login方法中处理

 1 public class LoginInteractorImpl implements LoginInteractor {
 2 
 3     @Override
 4     public void login(final String username, final String password, final OnLoginFinishedListener listener) {
 5         // Mock login. I'm creating a handler to delay the answer a couple of seconds
 6         new Handler().postDelayed(new Runnable() {
 7             @Override public void run() {
 8                 if (TextUtils.isEmpty(username)) {
 9                     listener.onUsernameError();
10                     return;
11                 }
12                 if (TextUtils.isEmpty(password)) {
13                     listener.onPasswordError();
14                     return;
15                 }
16                 listener.onSuccess();  //最终的数据处理这里作了临时的处理,调用listener的方法;实际项目会对作网络请求
17             }
18         }, 2000);
19     }
20 }

 【关键】关键是接口当中的方法的定义。

【接口总结】

【View的接口】

【1】将Activity与UI相关的动做所有暴露给Presenter,只负责更新UI。

【2】  由于View只负责更新UI,具体更新的时机由Prsenter直接决定,Model经过调用接口间接决定。Model调用的接口是:OnLoginFinishedListener,即被Prsenter的实现的Model的接口。

 1 public interface LoginView {
 2     void showProgress();
 3 
 4     void hideProgress();
 5 
 6     void setUsernameError();
 7 
 8     void setPasswordError();
 9 
10     void navigateToHome();   //view的页面的跳转
11 }

【Presenter接口】

1 public interface LoginPresenter {
2 
3     void validateCredentials(String username, String password);
4 
5     void onDestroy();
6 }

【1】包含数据参数的传递validateCredentials(String username, String password),View调用,经过Presenter中转,最终传递给Model处理。

1 /**
2      * 触发调用代理的方法
3      * @param v
4      */
5     @Override public void onClick(View v) { //在Acitivity中的调用
6   presenter.validateCredentials(username.getText().toString(), password.getText().toString());  }
 1  /**
 2      * 在执行登陆验证的动做:
 3      *  【1】触发view的动做
 4      *  【2】将参数传递给model
 5      * @param username
 6      * @param password
 7      */
 8     @Override public void validateCredentials(String username, String password) { //Presenter代理的实现  9         if (loginView != null) {
10             loginView.showProgress();
11         }
12 
13         loginInteractor.login(username, password, this); 
14     }

【2】onDestory()在Presenter中对View接口对象置空,等待gc。在Acitivity的OnDestory生命周期中调用此方法,释放view对象。

1  @Override public void onDestroy() {  //Presenter代理的实现 2         loginView = null;
3     }
1 @Override protected void onDestroy() { //在Acitivity生命周期中的调用 2         presenter.onDestroy();
3         super.onDestroy();
4     }

【Model接口】两部分:

 1 public interface LoginInteractor {
 2 
 3     interface OnLoginFinishedListener {  //被presenter实现的接口
 4         void onUsernameError();
 5         void onPasswordError();
 6         void onSuccess();
 7     }
 8 
 9     //对view传递的数据的处理,此处参数有presenter实现的接口对象 OnLoginFinishedListener
10     void login(String username, String password, OnLoginFinishedListener listener);
11 
12 }

【部分1】被Presenter实现的接口OnLoginFinishedListener ,是Presenter代理暴露出来的状态,对应于View的UI的更新。

 1  @Override public void onUsernameError() { //Presenter代理的实现  2         if (loginView != null) {
 3             loginView.setUsernameError();
 4             loginView.hideProgress();
 5         }
 6     }
 7 
 8     @Override public void onPasswordError() {  //Presenter代理的实现  9         if (loginView != null) {
10             loginView.setPasswordError();
11             loginView.hideProgress();
12         }
13     }
14 
15     @Override public void onSuccess() { //Presenter代理的实现 16         if (loginView != null) {
17             loginView.navigateToHome();
18         }
19     }

【部分2】对Acitivity传递过来的数据的处理。注意:其中将presenter实现的接口对象 OnLoginFinishedListener做为参数传递给了此方法,最终用来根据对数据处理的不一样的结果回调activity的UI更新。

1 //对view传递的数据的处理,此处参数有presenter实现的接口对象 OnLoginFinishedListener
2     void login(String username, String password, OnLoginFinishedListener listener);
 1 /**
 2      * 在执行登陆验证的动做:
 3      *  【1】触发view的动做
 4      *  【2】将参数传递给model
 5      * @param username
 6      * @param password
 7      */
 8     @Override public void validateCredentials(String username, String password) {
 9         if (loginView != null) {
10             loginView.showProgress();
11         }
12 
13         loginInteractor.login(username, password, this); //Presenter代理的调用 14     }
 1 public class LoginInteractorImpl implements LoginInteractor { //Model中的实现  2 
 3     @Override
 4     public void login(final String username, final String password, final OnLoginFinishedListener listener) {
 5         // Mock login. I'm creating a handler to delay the answer a couple of seconds
 6         new Handler().postDelayed(new Runnable() {
 7             @Override public void run() {
 8                 if (TextUtils.isEmpty(username)) {
 9                     listener.onUsernameError();
10                     return;
11                 }
12                 if (TextUtils.isEmpty(password)) {
13                     listener.onPasswordError();
14                     return;
15                 }
16                 listener.onSuccess();  //最终的数据处理这里作了临时的处理,调用listener的方法;实际项目会对作网络请求
17             }
18         }, 2000);
19     }
20 }

2.传统的mvp架构实例2

【功能】

【1】ListeView的数据设置

【2】item点击事件

【说明】一样也是三个接口,三个实现,两两一组

2.1 View

【view接口】

 1 public interface MainView {
 2 
 3     void showProgress();
 4 
 5     void hideProgress();
 6 
 7     void setItems(List<String> items); 
 8 
 9     void showMessage(String message);
10 }

 【view实现】

 1 public class MainActivity extends Activity implements MainView, AdapterView.OnItemClickListener {
 2 
 3     private ListView listView;
 4     private ProgressBar progressBar;
 5     private MainPresenter presenter;  //持有代理的对象
 6 
 7     @Override protected void onCreate(Bundle savedInstanceState) {
 8         super.onCreate(savedInstanceState);
 9         setContentView(R.layout.activity_main);
10         listView = (ListView) findViewById(R.id.list);
11         listView.setOnItemClickListener(this);
12         progressBar = (ProgressBar) findViewById(R.id.progress);
13         presenter = new MainPresenterImpl(this, new FindItemsInteractorImpl());  //生成代理,而且将model做为参数传递
14     }
15 
16     @Override protected void onResume() {
17         super.onResume();
18         presenter.onResume();
19     }
20 
21     @Override protected void onDestroy() {
22         presenter.onDestroy();
23         super.onDestroy();
24     }
25 
26     @Override public void showProgress() {
27         progressBar.setVisibility(View.VISIBLE);
28         listView.setVisibility(View.INVISIBLE);
29     }
30 
31     @Override public void hideProgress() {
32         progressBar.setVisibility(View.INVISIBLE);
33         listView.setVisibility(View.VISIBLE);
34     }
35 
36     @Override public void setItems(List<String> items) {
37         listView.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, items));
38     }
39 
40     @Override public void showMessage(String message) {
41         Toast.makeText(this, message, Toast.LENGTH_LONG).show();
42     }
43 
44     @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
45         presenter.onItemClicked(position);  //触发代理的item接口,将位置参数position传递
46     }
47 }

 【1】持有代理接口对象,此处持有的是接口对象,在构造LoginPresenterImpl时,即在View中new代理类对象时:直接传递了本身自己和model实现类。对接口进行了转化,将接口对象转化为了实现类(注意)

1 ......
2 private MainPresenter presenter;  //持有代理接口的对象
3 ......
4 presenter = new MainPresenterImpl(this, new FindItemsInteractorImpl());  //生成代理,而且将model做为参数传递

【2】实现接口

1 @Override public void setItems(List<String> items) {
2         listView.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, items));  //设置ListView的adpter 3     }

 【3】触发动做点击动做

1 @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //在listView的itemClick中触发presenter的接口的参数的传递 2         presenter.onItemClicked(position);  //触发代理的item接口,将位置参数position传递
3     }

 2.2 presenter 代理 

 【代理的接口】

1 public interface MainPresenter {
2 
3     void onResume();
4 
5     void onItemClicked(int position);
6 
7     void onDestroy();
8 }

 在看代理的实现以前先看下Model接口:presenter实现了此接口OnFinishedListener  

1 public interface FindItemsInteractor {
2 
3     interface OnFinishedListener {  //presenter实现了此接口 4         void onFinished(List<String> items);
5     }
6 
7     void findItems(OnFinishedListener listener);
8 }

 【代理接口的实现】

 1 public class MainPresenterImpl implements MainPresenter, FindItemsInteractor.OnFinishedListener {
 2 
 3     private MainView mainView; //持有view对象
 4     private FindItemsInteractor findItemsInteractor;  //持有model对象
 5 
 6     /**
 7      * 在构造方法中将view和presenter做为参数传递进来
 8      * @param mainView  view对象
 9      * @param findItemsInteractor  model对象
10      */
11     public MainPresenterImpl(MainView mainView, FindItemsInteractor findItemsInteractor) {
12         this.mainView = mainView;
13         this.findItemsInteractor = findItemsInteractor;
14     }
15 
16     @Override public void onResume() {
17         if (mainView != null) {
18             mainView.showProgress();
19         }
20         //对model中的
21         findItemsInteractor.findItems(this);
22     }
23 
24     /**
25      * 代理对view的点击事件的响应
26      * @param position
27      */
28     @Override public void onItemClicked(int position) {
29         if (mainView != null) {
30             mainView.showMessage(String.format("Position %d clicked", position + 1));
31         }
32     }
33 
34     @Override public void onDestroy() {
35         mainView = null;
36     }
37 
38     @Override public void onFinished(List<String> items) {
39         if (mainView != null) {
40             mainView.setItems(items);  //将Model返回的数据在View中进行了设置 --List<String>是Model返回的数据
41             mainView.hideProgress();
42         }
43     }
44 
45     public MainView getMainView() {
46         return mainView;
47     }
48 }

 代理主要完成下面的工做:

【1】在构造方法中持有view和model的对象

1 /**
2      * 在构造方法中将view和presenter做为参数传递进来
3      * @param mainView  view对象
4      * @param findItemsInteractor  model对象
5      */
6     public MainPresenterImpl(MainView mainView, FindItemsInteractor findItemsInteractor) {
7         this.mainView = mainView;
8         this.findItemsInteractor = findItemsInteractor;
9     }

【2】响应view的中Listview的itemClick的点击事件,onItemClicked直接获取位置position,经过Toast处理。

1  /**
2      * 代理对view的点击事件的响应
3      * @param position
4      */
5     @Override public void onItemClicked(int position) {
6         if (mainView != null) {
7             mainView.showMessage(String.format("Position %d clicked", position + 1));
8         }
9     }

【3】在onFinished接口回调中取回Model生成的数据List<String>,而后再经过回调,设置给View的Iitems,最终是将Model中的数据传给View,设置给ListView的Adapdter;

1  @Override public void onFinished(List<String> items) {
2         if (mainView != null) {
3             mainView.setItems(items);  //将Model返回的数据在View中进行了设置
4             mainView.hideProgress();
5         }
6     }

【4】发出请求给Model构造数据

1 @Override public void onResume() {
2         if (mainView != null) {
3             mainView.showProgress();
4         }
5         //对model中的
6         findItemsInteractor.findItems(this);
7     }

【5】将View的接口对象置空。被Acitivity在OnDestory()调用。

1 @Override public void onDestroy() {  //Presenter 实现 2         mainView = null;
3     }
1    @Override protected void onDestroy() {  //在Acitivity中调用 2         presenter.onDestroy();
3         super.onDestroy();
4     }

2.3 Model 

【接口】findItems方法中持有OnFinishedListener 接口,由于model须要构造数据,将数据经过OnFinishedListener 中的onFinished(List<String> items)方法中的参数List<String>将数据回调传递给Presenter,而后传递给View,最终设置给View中的ListView的Adapter。

1 public interface FindItemsInteractor {
2 
3     interface OnFinishedListener { //presenter实现了此接口
4         void onFinished(List<String> items);
5     }
6 
7     void findItems(OnFinishedListener listener);
8 }

 【Model接口的实现】

【1】createArrayList()对ListView的数据的构造

【2】接口OnFinishedListener的onFinished对 List<String>数据的回传。

 1 public class FindItemsInteractorImpl implements FindItemsInteractor {
 2     @Override public void findItems(final OnFinishedListener listener) {
 3         new Handler().postDelayed(new Runnable() {
 4             @Override public void run() {
 5                 listener.onFinished(createArrayList());
 6             }
 7         }, 2000);
 8     }
 9 
10     private List<String> createArrayList() {
11         return Arrays.asList(
12                 "Item 1",
13                 "Item 2",
14                 "Item 3",
15                 "Item 4",
16                 "Item 5",
17                 "Item 6",
18                 "Item 7",
19                 "Item 8",
20                 "Item 9",
21                 "Item 10"
22         );
23     }
24 }

2.4 总结

【1】模块的主要的功能有两个

  ①对Acitivity中的Listview的Item的点击事件的处理响应;

 ②Acitivity在获取焦点时触发presenter,让Model构造数据,而后从Model中取出生成的List<String> 数据设置给Activity中的ListView的Adapter。

【2】调用的顺序

【2-1】对Acitivity中的Listview的Item的点击事件的处理响应:注意:与Model没有发生联系

使用到了两个接口:

【接口1】(MainPresenter接口)onItemClicked(int position):将点击的position位置参数传递给代理实现类MainPresenterImpl;实现对int position参数的传递;

【接口2】(MainView接口) :showMessage(String message):将代理类中格式化好的position数据进行回传给MainView接口的实现类MainActivity;实现对String Message参数的传递;

 说白了,就是对position参数和String Message参数的回传;

 【2-2】Acitivity在获取焦点时触发presenter,让Model构造数据,而后从Model中取出生成的List<String> 数据设置给Activity中的ListView的Adapter。

 使用到了三个接口:上图中的【1-3】是属于view向Model发送请求,让Model构造数据;【3-5】由Model构造好的数据向View进行回传,而后最终设置给ListViewAdapter;

                                 是一个有去有回的过程,去的过程是发送信号,回的过程是回传数据。

 【接口1】(MainView--setItems(List<String> items)):回调Presenter已经构造好的数据,实现对List<String> items参数的回传;

 【接口2】(MainPresenter --void onResume())触发Model中的接口findItemsInteractor.findItems(this)进行数据的构造。

                 (MainPresenter --void onFinished(List<String> items) :完成对数据的回传,设置给MainView :mainView.setItems(items); //将nodel返回的数据在View中进行了设置

 【接口3】(FindItemsInteractor-->findItems(OnFinishedListener listener):触发Model构造数据

3. 传统的MVP架构的总结

 【1】构造三个接口,分别对应着View-Presenter-Model。两两一组。

 View接口:主要暴露给Presenter使用。

 1 public interface LoginView {
 2     void showProgress();
 3 
 4     void hideProgress();
 5 
 6     void setUsernameError();
 7 
 8     void setPasswordError();
 9 
10     void navigateToHome();   //view的页面的跳转
11 }
 1 public interface MainView {
 2 
 3     void showProgress();
 4 
 5     void hideProgress();
 6 
 7     void setItems(List<String> items);
 8 
 9     void showMessage(String message);
10 }

Presenter接口:

1 public interface LoginPresenter {
2 
3     void validateCredentials(String username, String password);
4 
5     void onDestroy();
6 }
1 public interface MainPresenter {
2 
3     void onResume();
4 
5     void onItemClicked(int position);
6 
7     void onDestroy();
8 }

 Model接口:

    两部分构成,一部分是给Presenter实现的Listener,主要是Model对View的数据回传、状态的回调,主要是被Model调用。

                          另一部分是View传递的数据处理/请求,被View调用的方法。

 1 public interface LoginInteractor {
 2 
 3     interface OnLoginFinishedListener {  //被presenter实现的接口
 4         void onUsernameError();
 5         void onPasswordError();
 6         void onSuccess();
 7     }
 8 
 9     //对view传递的数据的处理,此处参数有presenter实现的接口对象 OnLoginFinishedListener
10     void login(String username, String password, OnLoginFinishedListener listener);
11 
12 }
1 public interface FindItemsInteractor {
2 
3     interface OnFinishedListener { //presenter实现了此接口
4         void onFinished(List<String> items);
5     }
6 
7     void findItems(OnFinishedListener listener);
8 }

【2】Acitivity只负责UI更新和数据设置。

        在Acitivity中持有Presenter的接口对象。

        Activity中控件具备的显示/更新/数据的设置(ListView的Adapter)/数据的处理(登陆名和密码的传递)以接口的形式暴露给Prsenter。只容许Presenter操做。

        Acitivity的控件的更新时机交给Presenter直接决定,由Model间接决定。

【3】在Presenter中同时持有view和Model的接口对象。

【4】Presenter中除了实现自己的接口presenter接口,还须要实现Model对应的接口中的内部接口。

    内部接口主要完成对状态的回传或者是数据的回传。

源码地址:

相关文章
相关标签/搜索