1、MVP是什么?
mvp(Model-View-Presenter)是一种架构,在Android中相比MVC而言,耦合度更低,可扩展性更好
1、Presenter:持有View、Model的接口类型对象(面向接口编程,保证了良好的可扩展性)
2、View:视图,Android中一般是Activity、Fragment,它持有Presenter对象
3、Model:用于处理业务逻辑(比如从服务器获取数据)
1.1、本示例要完成的效果如下:
很简单的需求,主页面有一个ListView,展示从服务器获取的数据。
![效果图](https://img-blog.csdn.net/20170404144420103?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMTQxMjIzNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
项目结构如下:
类图如下:
2、代码如下:
2.1 Model 业务逻辑包
/**
* 业务逻辑接口(具体业务逻辑在实现类中)
*
* 为什么要用接口?
* 因为业务逻辑随时可能会变,
*/
public interface IMainModel
{
/**
* 从服务器加载数据
*
* @param listener
*/
void loadData(OnLoadDataListener listener);
/**
* 加载数据的回调
*/
interface OnLoadDataListener
{
void onComplete(ArrayList<HashMap<String, Object>> listData);
}
}
/**
* 业务逻辑实现类
*/
public class MainModel implements IMainModel
{
@Override
public void loadData(OnLoadDataListener listener)
{
//这里模拟成吨的假数据
ArrayList listData = new ArrayList<HashMap<String, Object>>();
HashMap<String, Object> map1 = new HashMap<String, Object>();
map1.put("img", R.drawable.a1);
map1.put("text", "我是天才,哈哈哈哈哈");
HashMap<String, Object> map2 = new HashMap<String, Object>();
map2.put("img", R.drawable.a2);
map2.put("text", "我是天才,哈哈哈哈哈");
HashMap<String, Object> map3 = new HashMap<String, Object>();
map3.put("img", R.drawable.a3);
map3.put("text", "我是天才,哈哈哈哈哈");
HashMap<String, Object> map4 = new HashMap<String, Object>();
map4.put("img", R.drawable.a4);
map4.put("text", "我是天才,哈哈哈哈哈");
HashMap<String, Object> map5 = new HashMap<String, Object>();
map5.put("img", R.drawable.a5);
map5.put("text", "我是天才,哈哈哈哈哈");
HashMap<String, Object> map6 = new HashMap<String, Object>();
map6.put("img", R.drawable.a6);
map6.put("text", "我是天才,哈哈哈哈哈");
HashMap<String, Object> map7 = new HashMap<String, Object>();
map7.put("img", R.drawable.a7);
map7.put("text", "我是天才,哈哈哈哈哈");
listData.add(map1);
listData.add(map2);
listData.add(map3);
listData.add(map4);
listData.add(map5);
listData.add(map6);
listData.add(map7);
//加载完成回调
listener.onComplete(listData);
}
}
2.2 View 接口
/**
* 视图接口(通常activity、fragment需要实现该接口,具体业务逻辑在activity、fragment中)
*/
public interface IMainView
{
/**
* 加载完成
*/
void onLoadComplete(ArrayList<HashMap<String, Object>> listData);
/**
* 加载失败
*/
void onLoadError(String errorText);
void onLoadStart();
}
2.3 presenter
/**
* 负责完成View于Model间的交互
*/
public class MainPresenter
{
/*
* 以下两个成员变量 View、Model为什么要使用接口类型对象?
* 1、View:如果另一个activity也要展示相同的页面,只需要继承IMainView接口,调用该presenter的fetch方法即可
*
* 2、Model:如果业务逻辑,换一个实现类即可
*
* (本质上都是换一个接口的实现类)
*/
private IMainView mainView;
private IMainModel mainModel = new MainModel();
public MainPresenter(IMainView mainView)
{
this.mainView = mainView;
}
public void fetch()
{
mainView.onLoadStart();
mainModel.loadData(new IMainModel.OnLoadDataListener()
{
@Override
public void onComplete(ArrayList<HashMap<String, Object>> listData)
{
mainView.onLoadComplete(listData);
}
});
}
}
2.3 MainActivity
public class MainActivity extends AppCompatActivity implements IMainView
{
private ArrayList<HashMap<String, Object>> listData;
private ListView listView;
private MainPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView);
initData();
}
/**
* 加载数据
*/
private void initData()
{
presenter = new MainPresenter(this);
presenter.fetch();
}
@Override
public void onLoadComplete(ArrayList<HashMap<String, Object>> listData)
{
listView.setAdapter(new MyAdapter(this, listData));
}
@Override
public void onLoadError(String errorText)
{
Toast.makeText(this, errorText, Toast.LENGTH_SHORT).show();
}
@Override
public void onLoadStart()
{
Toast.makeText(this, "开始加载", Toast.LENGTH_SHORT).show();
}
}
示例代码请点击