MVP模式的簡單應用
阿新 • • 發佈:2018-11-02
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模式進行抽取封裝。