mvp的全称为Model-View-Presenter,Model提供数据,View负责显示,Controller/Presenter负责逻辑的处理。MVP与MVC有着1个重大的区分:在MVP中View其实不直接使用Model,它们之间的通讯是通过Presenter
(MVC中的Controller)来进行的,所有的交互都产生在Presenter内部,而在MVC中View会直接从Model中读取数据而不是通过 Controller。
项目中大部份是面对接口编程,通过P层可以预先将所有需要的接口功能写出来,进而进行实现,大大提高了项目高内聚,低耦合。合适于团队开发项目。
今天我们是用MVP的设计框架模板来实现1个ListView的上拉刷新下拉加载更多的功能。
项目结构以下图;
1、首先我们ListViewPresenters.java类,他的作用是,控制M业务逻辑层,去获得我们想要的数据,然后通知V层去更新他们对应的UI。由于我们的需求明确,就是实现Listview的上拉刷新,下拉加载更多,初始化控件,设置上拉下拉刷新监听。因此我们可以先把功能接口都写好,让ListViewPresenters去实现其功能便可。
package com.android.presenters;
import java.util.ArrayList;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import com.android.handlers.ListViewHandle;
import com.android.services.ListViewService;
import com.android.services.si.IListViewService;
import com.android.view.ListViewFerris;
import com.android.view.vi.IListViewFerris;
import com.android.widget.listview.FerrisListView.OnStartListener;
public class ListViewPresenters {
private IListViewFerris iListViewFerris;
private IListViewService iListViewService;
private FragmentActivity mActivity;
private View view;
private int index = 1;
public ListViewPresenters(FragmentActivity mActivity2, View view2) {
// TODO Auto-generated constructor stub
this.mActivity = mActivity2;
this.view = view2;
this.iListViewFerris = new ListViewFerris(mActivity, view);
this.iListViewService = new ListViewService();
}
/*
* 初始化View层里的控件
*/
public void onFindView() {
iListViewFerris.onFindView();
}
/*
* 上啦刷新方法
*/
public void listViewRefresh(int index) {
//post要求数据,获得数据,并且通过handler接口来通知View更新UI
iListViewService.sendPost(index, new ListViewHandle() {
@Override
public void getData(ArrayList<String> msgs) {
// TODO Auto-generated method stub
//通过handler接口来通知UI去更新数据
iListViewFerris.refresh(msgs);
}
});
}
/*
* 下拉加载更多方法
*/
public void listViewLoadMore(int index) {
//post要求数据,获得数据,并且通过handler接口来通知View更新UI
iListViewService.sendPost(index, new ListViewHandle() {
@Override
public void getData(ArrayList<String> msgs) {
// TODO Auto-generated method stub
//通过handler接口来通知UI去更新数据
if (msgs == null) {
iListViewFerris.showLoadingError();//获得数据失败显示通知
iListViewFerris.loadMore(msgs);//停止加载更多
} else {
iListViewFerris.loadMore(msgs);//停止加载更多
}
}
});
}
/*
* 为Listview设置上拉下拉刷新监听
*/
public void setRefreshOrLoadMoreListem() {
// TODO Auto-generated method stub
iListViewFerris.setRefreshOrLoadMoreListem(new Refresh(),
new Loadmore());
}
/*
* 为Listview第1次,自动下拉刷新
*/
public void firstload() {
// TODO Auto-generated method stub
iListViewFerris.firstLoad();
}
/*
* 上拉刷新监听
*/
public class Refresh implements OnStartListener {
@Override
public void onStart() {
// TODO Auto-generated method stub
index = 1;
listViewRefresh(index);
}
}
/*
* 加载更多监听
*/
public class Loadmore implements OnStartListener {
@Override
public void onStart() {
// TODO Auto-generated method stub
listViewLoadMore(++index);
}
}
}
2、接着我们来看下UI层,我们需要更新哪些数据,需要为哪一个UI去具体更新哪些东西。
package com.android.view.vi;
import java.util.ArrayList;
import com.android.widget.listview.FerrisListView.OnStartListener;
public interface IListViewFerris {
public void onFindView();//初始化控件
public void showLoadingError();//显示加载毛病
public void showLoadingSuccess();//显示加成功
public void setNotifyListView();//刷新Listview
public void refresh(ArrayList<String> msgs);//上拉刷新
public void loadMore(ArrayList<String> msgs);//下拉加载更多
public void setRefreshOrLoadMoreListem(OnStartListener refresh, OnStartListener loadmore);//设置上拉下拉刷新监听
public void firstLoad();//首次自动上拉刷新
}
具体UI层实现的具体方法,主要是 上拉刷新,下拉加载更多,显示毛病成功状态,和初始化控件等方法。
package com.android.view;
import java.util.ArrayList;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import com.android.adapter.ListViewAdapter;
import com.android.futilssimple.R;
import com.android.utils.ToastUtils;
import com.android.view.vi.IListViewFerris;
import com.android.widget.listview.FerrisListView;
import com.android.widget.listview.FerrisListView.OnStartListener;
import com.android.widget.listview.SimpleFooter;
import com.android.widget.listview.SimpleHeader;
public class ListViewFerris implements IListViewFerris{
private FragmentActivity mActivity;
private View view;
private FerrisListView listView;
private ListViewAdapter adapter;
public ListViewFerris(FragmentActivity mActivity,View view) {
// TODO Auto-generated constructor stub
this.mActivity=mActivity;
this.view=view;
}
//初始化view
@Override
public void onFindView() {
// TODO Auto-generated method stub
if(mActivity==null||view==null){
return;
}
listView = (FerrisListView)view.findViewById(R.id.zListView);
adapter=new ListViewAdapter(mActivity);
// 设置默许偏移量,主要用于实现透明标题栏功能。(可选)
float density = mActivity.getResources().getDisplayMetrics().density;
listView.setFirstTopOffset((int) (50 * density));
// 设置下拉刷新的样式(可选,但如果没有Header则没法下拉刷新)
SimpleHeader header = new SimpleHeader(mActivity);
header.setTextColor(0xff0066aa);
header.setCircleColor(0xff33bbee);
listView.setHeadable(header);
// 设置加载更多的样式(可选)
SimpleFooter footer = new SimpleFooter(mActivity);
footer.setCircleColor(0xff33bbee);
listView.setFootable(footer);
}
//显示加载失败
@Override
public void showLoadingError() {
// TODO Auto-generated method stub
ToastUtils.showToast(mActivity, "加载失败");
}
//显示加载成功
@Override
public void showLoadingSuccess() {
// TODO Auto-generated method stub
ToastUtils.showToast(mActivity, "加载成功");
}
//刷新数据
@Override
public void setNotifyListView() {
// TODO Auto-generated method stub
if(adapter!=null){
adapter.notifyDataSetChanged();
}
}
//填充刷新数据
@Override
public void refresh(ArrayList<String> msgs) {
// TODO Auto-generated method stub
if(msgs!=null&&msgs.size()>0){
if(listView.getAdapter()==null){
listView.setAdapter(adapter);
adapter.setRefresh(msgs);
}else{
adapter.setRefresh(msgs);
}
listView.setRefreshSuccess("加载成功"); // 通知加载成功
listView.startLoadMore(); // 开启LoadingMore功能
}else{
listView.setRefreshFail("加载失败");
}
}
//填充加载更多数据
@Override
public void loadMore(ArrayList<String> msgs) {
// TODO Auto-generated method stub
if(msgs!=null&&msgs.size()>0){
if(listView.getAdapter()==null){
listView.setAdapter(adapter);
adapter.setData(msgs);
}else{
adapter.setData(msgs);
}
listView.setLoadMoreSuccess();
}else{
listView.stopLoadMore();
}
}
//为Listview设置首次自动上拉刷新
@Override
public void firstLoad(){
listView.refresh(); // 主动下拉刷新
}
//为Listview设置上拉和下拉刷新
@Override
public void setRefreshOrLoadMoreListem(OnStartListener refresh,
OnStartListener loadmore) {
// TODO Auto-generated method stub
listView.setOnRefreshStartListener(refresh);
listView.setOnLoadMoreStartListener(loadmore);
}
}
3、我们来看下业务逻辑层,主要是通过摹拟POST在后台要求数据,然后将获得的数据,返回给P层,由P层去将数据交予V层来更新UI界面。
package com.android.services.si;
import com.android.handlers.ListViewHandle;
public interface IListViewService {
//发送post要求
public void sendPost(int index,ListViewHandle handle);
}
业务逻辑才具体实现的功能以下:
package com.android.services;
import java.util.ArrayList;
import android.os.Handler;
import com.android.futils.task.FTaskPool;
import com.android.futils.task.TaskItem;
import com.android.handlers.ListViewHandle;
import com.android.services.si.IListViewService;
public class ListViewService implements IListViewService {
String[] data={"加拿大","瑞典","澳大利亚","瑞士","新西兰","挪威","丹麦","芬兰","奥地利","荷兰","德国","日本","比利时","意大利","英国"};
public ListViewService() {
// TODO Auto-generated constructor stub
}
private Handler handler=new Handler();
private ArrayList<String> msgs;
@Override
public void sendPost(int index, ListViewHandle handle) {
// TODO Auto-generated method stub
switch (index) {
case 1:
getData(index,handle);
break;
case 2:
getData(index,handle);
break;
case 3:
getData(index,handle);
break;
case 4:
getData(index,handle);
break;
case 5:
getData(index,handle);
break;
case 6:
getData(index,handle);
break;
default:
msgs=null;
handle.getData(msgs);
break;
}
}
private synchronized void getData(final int index, final ListViewHandle handle) {
// TODO Auto-generated method stub
handler.postDelayed(new Runnable() {
@Override
public void run() {
FTaskPool.getInstance().execute(new TaskItem() {
@Override
public void doMain() {//在前台显示数据
// TODO Auto-generated method stub
if(handle!=null){
handle.getData(msgs);
}
}
@Override
public void doBack() {//在后台处理数据
// TODO Auto-generated method stub
msgs=new ArrayList<String>();
for(String d:data){
msgs.add(index+"、"+d);
}
}
});
}
}, 2 * 1000);//延迟2秒后履行
}
}
4、最后,我们来看下Fragment里面如来调用这个P层,来控制MV进行数据的获得和更新
package com.android.fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.android.futilssimple.R;
import com.android.presenters.ListViewPresenters;
public class ListViewFragment extends Fragment {
private ListViewPresenters listViewPresenters;
public ListViewFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.listviewfragment, container, false);
listViewPresenters=new ListViewPresenters(getActivity(), rootView);//新建1个控制器
listViewPresenters.onFindView();//初始化view
listViewPresenters.setRefreshOrLoadMoreListem();//设置刷新监听
listViewPresenters.firstload();//首次自动上拉刷新
return rootView;
}
}
5、源码demo
http://download.csdn.net/detail/xufeifandj/8369037