mvp理解的外文地址:http://antonioleiva.com/mvp-android/
github实例地址:https://github.com/antoniolg/androidmvp
MVP模式是如何工作的
MVP
模式中的角色划分并没有标准的划分方法。大致的定义如下:
-
表示器(Presenter)
表示器也可以称为指挥器,它处在View和Model之间,负责从Model中获取数据,然后返回给View。同时决定视图上的交互的处理。 -
视图(View)
视图比较好理解,在Android中一般对应的是Activity
,Fragment
或者View
。因为视图上的交互需要通知表示器,让它决定做什么事情。所以View中一般包含一个Presenter的引用。理想状况下,Presenter一般使用依赖注入的方式实现。 -
模型(Model)
模型是应用程序中的数据处理和业务逻辑部分。
MVP处理流程如下图所示:
个人理解MVP模式里通常包含4个要素:
(1)
View:负责绘制UI元素、与用户进行交互(在Android中体现为Activity);
(2
)View interface:需要View实现的接口,View通过View interface与Presenter进行交互,降低耦合,方便进行单元测试;
(3)
Model:负责存储、检索、操纵数据(有时也实现一个Model interface用来降低耦合);
(4)
Presenter:作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。
实例:下面的代码完全没有合理性,仅仅体现以下Mvp
1、User 类
public class User {
public int id;
public String name;
public User() {
}
public User(int id,String name) {
this.id = id;
this.name = name;
}
}
2、UserModel类
public interface UserModel {
public void addUser(User user);
public List<User> loadUser();
}
3、UserModelImpl类
public class UserModelImpl implements UserModel {
//模拟数据库
List<User> data = new ArrayList<>();
@Override
public void addUser(User user) {
data.add(user);
}
@Override
public List<User> loadUser() {
//模拟获取数据
return new ArrayList<>(data);
}
}
4、UserPresenter类
public class UserPresenter {
private UserModel mUserModel;
private UserView mUserView;
public UserPresenter(UserView userView) {
mUserView = userView;
mUserModel = new UserModelImpl();
}
public void addUser() {
mUserModel.addUser(new User(new Random().nextInt(),mUserView.getName()));
}
public void updateUserList() {
List<User> users = mUserModel.loadUser();
List<String> names = new ArrayList<>();
for(int i=0;i<users.size();i++) {
names.add(users.get(i).name);
}
mUserView.updateNameList(names);
}
}
5、UserView类
public interface UserView {
public String getName();
public void updateNameList(List<String> users);
}
6、UserActivity类
public class UserActivity extends Activity implements UserView,View.OnClickListener {
private EditText mName;
private Button mSubmit;
private Button mQuery;
private ListView mNameList;
private UserPresenter mPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user);
mName = (EditText) findViewById(R.id.name);
mSubmit = (Button) findViewById(R.id.submit);
mQuery = (Button) findViewById(R.id.query);
mNameList = (ListView) findViewById(R.id.name_list);
mSubmit.setOnClickListener(this);
mQuery.setOnClickListener(this);
mPresenter = new UserPresenter(this);
}
@Override
public String getName() {
return mName.getText().toString();
}
@Override
public void updateNameList(List<String> users) {
mNameList.setAdapter(new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,users));
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.submit:
mPresenter.addUser();
break;
case R.id.query:
mPresenter.updateUserList();
break;
}
}
}
7、activity_user.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/name_label"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:gravity="left|center_vertical"
android:text="姓名:"/>
<EditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_toRightOf="@id/name_label"
android:hint="请输入姓名"/>
<Button
android:id="@+id/submit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/name"
android:layout_marginTop="10dp"
android:text="提交"/>
<Button
android:id="@+id/query"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/submit"
android:layout_marginTop="5dp"
android:text="查询"/>
<ListView
android:id="@+id/name_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/query"
android:layout_marginTop="10dp">
</ListView>
</RelativeLayout>