MVP模式的简单应用
程序员文章站
2024-03-15 19:38:36
...
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);
}
}
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();
}
}
/**
* 将原本写在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模式进行抽取封装。