標籤:
mvp的全稱為Model-View-Presenter,Model提供資料,View負責顯示,Controller/Presenter負責邏輯的處理。MVP與MVC有著一個重大的區別:在MVP中View並不直接使用Model,它們之間的通訊是通過Presenter (MVC中的Controller)來進行的,所有的互動都發生在Presenter內部,而在MVC中View會直接從Model中讀取資料而不是通過 Controller。
項目中大部分是面對介面編程,通過P層可以預先將所有需要的介面功能寫出來,進而進行實現,大大提高了項目高內聚,低耦合。適合於團隊開發項目。
今天我們是用MVP的設計架構模板來實現一個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 stubthis.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更新UIiListViewService.sendPost(index, new ListViewHandle() {@Overridepublic void getData(ArrayList<String> msgs) {// TODO Auto-generated method stub//通過handler介面來通知UI去更新資料iListViewFerris.refresh(msgs);}});}/* * 下拉載入更多方法 */public void listViewLoadMore(int index) {//post請求資料,擷取資料,並且通過handler介面來通知View更新UIiListViewService.sendPost(index, new ListViewHandle() {@Overridepublic 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 stubiListViewFerris.setRefreshOrLoadMoreListem(new Refresh(),new Loadmore());}/* * 為Listview第一次,自動下拉重新整理 */public void firstload() {// TODO Auto-generated method stubiListViewFerris.firstLoad();}/* * 上拉重新整理監聽 */public class Refresh implements OnStartListener {@Overridepublic void onStart() {// TODO Auto-generated method stubindex = 1;listViewRefresh(index);}}/* * 載入更多監聽 */public class Loadmore implements OnStartListener {@Overridepublic void onStart() {// TODO Auto-generated method stublistViewLoadMore(++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();//重新整理Listviewpublic 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 stubthis.mActivity=mActivity;this.view=view;}//初始化view@Overridepublic void onFindView() {// TODO Auto-generated method stubif(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);}//顯示載入失敗@Overridepublic void showLoadingError() {// TODO Auto-generated method stubToastUtils.showToast(mActivity, "載入失敗");}//顯示載入成功@Overridepublic void showLoadingSuccess() {// TODO Auto-generated method stubToastUtils.showToast(mActivity, "載入成功");}//重新整理資料@Overridepublic void setNotifyListView() {// TODO Auto-generated method stubif(adapter!=null){adapter.notifyDataSetChanged();}}//填充重新整理資料@Overridepublic void refresh(ArrayList<String> msgs) {// TODO Auto-generated method stubif(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("載入失敗");}}//填充載入更多資料@Overridepublic void loadMore(ArrayList<String> msgs) {// TODO Auto-generated method stubif(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設定首次自動上拉重新整理@Overridepublic void firstLoad(){listView.refresh(); // 主動下拉重新整理}//為Listview設定上拉以及下拉重新整理@Overridepublic void setRefreshOrLoadMoreListem(OnStartListener refresh,OnStartListener loadmore) {// TODO Auto-generated method stublistView.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;@Overridepublic void sendPost(int index, ListViewHandle handle) {// TODO Auto-generated method stubswitch (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);//建立一個控制器 listViewPresenters.onFindView();//初始化view listViewPresenters.setRefreshOrLoadMoreListem();//設定重新整理監聽 listViewPresenters.firstload();//首次自動上拉重新整理 return rootView; } }
5、源碼demo稍後上傳
Android MVP設計架構模板 之 漂亮ListView上拉重新整理下拉載入更多