欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MVP模式的简单应用

程序员文章站 2024-03-15 19:38:36
...


MVP :

  • M-model,即javaBean 数据模型层;
  • V-view,视图层,常用的即Activity Fragment,这里是定义一个接口IView,Activity去实现IView的写法;
  • P-presenter,数据处理层,所有的数据逻辑,业务逻辑都在这里处理;

详细介绍就不多说,自己写一个Demo,基本就能理解;

MVP 实例:获取图片数据,并用ListView进行展示

效果图:

MVP模式的简单应用


包结构:

MVP模式的简单应用


代码:

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模式进行抽取封装。