1. 程式人生 > >MVP模式的簡單應用

MVP模式的簡單應用


MVP :

  • M-model,即javaBean 資料模型層;
  • V-view,檢視層,常用的即Activity Fragment,這裡是定義一個介面IView,Activity去實現IView的寫法;
  • P-presenter,資料處理層,所有的資料邏輯,業務邏輯都在這裡處理;

詳細介紹就不多說,自己寫一個Demo,基本就能理解;

MVP 例項:獲取圖片資料,並用ListView進行展示

效果圖:



包結構:



程式碼:

M:MainGetImgModel


/**
 * 獲取資料的Model
 * */
public class MainGetImgModel {
	//網路圖片地址
	private String[] imgArr = { 
			"http://img02.sogoucdn.com/app/a/100520076/41c3c06da0ab59719a3d1b9c839b72cc",
			"http://img03.sogoucdn.com/app/a/100520076/25682e62dd4b2ac15f89d24b88c31aaa",
			"http://img02.sogoucdn.com/app/a/100520076/e3fd14fc3b20eca09b740c96da4472b7",
			"http://img01.sogoucdn.com/app/a/100520020/0b37d30dc7017f35c2c4d78732066baa" };

	public void loadData(final MyCallBack callBack) {
		//模擬執行緒請求
		new Thread(new Runnable() {
			public void run() {
				List<String> mList = new ArrayList<String>();
				for (int i = 0; i < imgArr.length; i++) {
					mList.add(imgArr[i]);
				}
				// 休眠兩秒,用於展示載入框
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				} //結果回撥
				callBack.onFinish(mList);
			}
		}).start();
	}
	// 請求回撥
	public interface MyCallBack{
		void onFinish(List<String> mList);
	}
}


V:MainActivity

 IView :抽取的 MainActivity 的介面


/**
 * MainActivity 的介面
 * 操作View 的相關方法
 * */
public interface MainIView {
	// 展示旋轉框
	void showProgressBar();
	// 隱藏旋轉框
	void hideProgress();
	// 請求的資料,展示到View 上
	void showImg(List<String> mList);
}


 View :MainActivity


/**
 * 展示請求到的圖片資料
 */
public class MainActivity extends Activity implements MainIView {
	private ListView mListView;
	private ProgressBar mBar;
	private MainPresenter mPrestener;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mListView = (ListView) findViewById(R.id.main_lv);
		mBar = (ProgressBar) findViewById(R.id.main_pb);
		// 初始化 Presneter ,並請求資料
		mPrestener = new MainPresenter(this);
		mPrestener.loadData();
	}

	@Override
	public void showProgressBar() {
		mBar.setVisibility(View.VISIBLE);
	}

	@Override
	public void hideProgress() {
		mBar.setVisibility(View.GONE);
	}

	@Override
	public void showImg(List<String> mList) {
		// 給ListView設定資料
		MainAdapter adapter = new MainAdapter(MainActivity.this, mList);
		mListView.setAdapter(adapter);
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		// 釋放presenter
		if (mPrestener != null)
			mPrestener.destory();
	}
}


P: MainPresenter.class


/**
 * 將原本寫在Activity或Fragment 中的邏輯寫到這裡
 * Model與View 的互動
 * */
public class MainPresenter {
	private MainGetImgModel mImgModel;
	private MainIView mainIView;

	public MainPresenter(MainIView mainIView) {
		mImgModel = new MainGetImgModel();
		this.mainIView = mainIView;
	}

	private Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			if (msg.what == 1) {
				List<String> mList = (List<String>) msg.obj;
				// 將資料傳送至View
				mainIView.showImg(mList);
				// 隱藏旋轉框
				mainIView.hideProgress();
			}
		};
	};
	/**
	 * 呼叫Model中的載入資料的方法
	 * 並與View 結合
	 * */
	public void loadData() {
		// 顯示旋轉框
		mainIView.showProgressBar();
		//請求資料
		mImgModel.loadData(new MyCallBack() {
			@Override
			public void onFinish(List<String> mList) {
				//請求成功,將結果傳送至主執行緒中。
				Message message = handler.obtainMessage();
				message.obj = mList;
				message.what = 1;
				handler.sendMessage(message);
			}
		});
	}
	// 釋放記憶體。(防止記憶體洩漏)
	public void destory() {
		if (mainIView != null)
			mainIView = null;
		if (handler != null)
			handler.removeCallbacksAndMessages(null);
	}
}


其他:

 Adapter:


public class MainAdapter extends BaseAdapter {
	private Context mContext;
	private List<String> mList;

	public MainAdapter(Context mContext, List<String> mList) {
		this.mContext = mContext;
		this.mList = mList;
	}

	@Override
	public int getCount() {
		return mList != null ? mList.size() : 0;
	}

	@Override
	public Object getItem(int position) {
		return mList != null ? mList.get(position) : null;
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder holder = null;
		if (convertView == null) {
			convertView = View.inflate(mContext, R.layout.item, null);
			holder = new ViewHolder(convertView);
			convertView.setTag(holder);
		} else {
			holder = (ViewHolder) convertView.getTag();
		}
		Log.d("lijia", "handleMessage 28" + mList.get(position));
		Glide.with(mContext).load(mList.get(position)).into(holder.imageView);
		return convertView;
	}

	class ViewHolder implements AbsBaseAdapter.IViewHolder {
		private ImageView imageView;

		public ViewHolder(View view) {
			if (view == null)
				return;
			imageView = (ImageView) view.findViewById(R.id.item_iv);
		}
	}
}


 佈局:

  activity_main.xml:


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.mvpdemo.view.MainActivity" >

    <ProgressBar
        android:visibility="gone"
        android:id="@+id/main_pb"
        android:layout_centerInParent="true"
        android:layout_width="120dp"
        android:layout_height="120dp" />

    <ListView
        android:id="@+id/main_lv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </ListView>

</RelativeLayout>
 

item.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <ImageView
        android:id="@+id/item_iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

寫個Demo對於理解MVP 模式是很有幫助的。但是,專案中這樣寫還是有很多問題的。

後面會對 MVP模式進行抽取封裝。