關(guān)于MVP侠坎,已經(jīng)不是什么新鮮的東西了硅急,網(wǎng)上的教程也是一摞一摞的甩栈,我當(dāng)初看的是焦頭爛額隘弊,看了半天還是不知道怎么用。送悔。慢显。
現(xiàn)在就跟著我思路,來看看MVP到底怎么寫欠啤,當(dāng)然這之前你得知道什么是MVP荚藻。
Talk is cheap,Show you the code!
public interface IContract {
interface Model {
List<String> download();//下載數(shù)據(jù);
void getData(OnGetDataLinstener getDataLinstener);//模擬網(wǎng)絡(luò)獲取數(shù)據(jù)
interface OnGetDataLinstener{
void successful(String s);//成功后的接口回調(diào)
void failed();//失敗后的接口回調(diào)
}
}
interface View {
void setList(List<String> list);//給listview設(shè)置數(shù)據(jù)
void toast(String s);
}
interface Presenter {
void startDown();//開始下載數(shù)據(jù)
}
}
1.Presenter接口
Presenter 這個(gè)接口呢跪妥,主要是寫業(yè)務(wù)邏輯的鞋喇,將Model中產(chǎn)生的數(shù)據(jù)拿過來刷新View声滥,所有的方法都是圍繞這個(gè)主題建立的眉撵;
它的實(shí)現(xiàn)類是直接跟Activity接觸的;
要注意它的實(shí)現(xiàn)類的有參構(gòu)造方法內(nèi)要放入View接口落塑,并且在方法中new出Model的實(shí)現(xiàn)類纽疟;
public IPresenter(IContract.View iv) {
this.iv = iv;
m = new IModel();
}
在有參構(gòu)造中放入View的接口是為了在new IPresenter的時(shí)候讓Activity實(shí)現(xiàn)View接口的方法,從而實(shí)現(xiàn)刷新View的目的憾赁。
在IPresenter中從Model中的方法獲取數(shù)據(jù)污朽,然后刷新給View,就是具體的業(yè)務(wù)邏輯了
public class IPresenter implements IContract.Presenter, IContract.Model.OnGetDataLinstener {
IContract.View iv;
IContract.Model m;
public IPresenter(IContract.View iv) {
this.iv = iv;
m = new IModel();
}
@Override
public void startDown() {
List<String> download = m.download();//獲取本地?cái)?shù)據(jù)
iv.setList(download);//給View設(shè)置數(shù)據(jù)
m.getData(this);//獲取網(wǎng)絡(luò)數(shù)據(jù)龙考,并實(shí)現(xiàn)回調(diào)接口
}
//成功之后的回調(diào)
@Override
public void successful(String s) {
Log.d("IPresenter", s);
iv.toast(s);
}
@Override
public void failed() {
}
}
2.Model接口
這個(gè)接口沒啥好說的了蟆肆,就是具體的一些獲取數(shù)據(jù)的邏輯,注意寫個(gè)回調(diào)接口獲取數(shù)據(jù)就行了
public class IModel implements IContract.Model {
List<String> list = new ArrayList<>();
@Override
public List<String> download() {
//假設(shè)的本地?cái)?shù)據(jù)
for (int i = 0; i < 100; i++) {
list.add(i + "");
}
return list;
}
@Override
public void getData(final OnGetDataLinstener getDataLinstener) {
OkGo.get("http://11.11.11.11:9099/api/Company/GetCompanyList") // 請(qǐng)求方式和請(qǐng)求url
.tag(this) // 請(qǐng)求的 tag, 主要用于取消對(duì)應(yīng)的請(qǐng)求
.cacheKey("cacheKey") // 設(shè)置當(dāng)前請(qǐng)求的緩存key,建議每個(gè)不同功能的請(qǐng)求設(shè)置一個(gè)
.cacheMode(CacheMode.DEFAULT) // 緩存模式晦款,詳細(xì)請(qǐng)看緩存介紹
.execute(new StringCallback() {
@Override
public void onSuccess(String s, Call call, Response response) {
getDataLinstener.successful(s);//數(shù)據(jù)獲取成功后的回調(diào)
}
@Override
public void onError(Call call, Response response, Exception e) {
super.onError(call, response, e);
getDataLinstener.failed();//獲取數(shù)據(jù)失敗后的回調(diào)
}
});
}
}
3.View接口
這個(gè)接口就是負(fù)責(zé)展示的邏輯炎功,它沒有實(shí)現(xiàn)類,因?yàn)樗窃贏ctivity中具體實(shí)現(xiàn)的
public class MainActivity extends AppCompatActivity implements IContract.View {
private ListView lv;
private List<String> strings;
private TextView mTv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
OkGo.init(getApplication());
initview();
IPresenter iPresenter = new IPresenter(this);
iPresenter.startDown();
}
private void initview() {
mTv = (TextView) findViewById(R.id.tv);
lv = (ListView) findViewById(R.id.lv);
}
@Override
public void setList(List<String> list) {
Log.d("MainActivity", "111:" + 111);
ArrayAdapter<String> myAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, list);//適配器
lv.setAdapter(myAdapter);
}
@Override
public void toast(String s) {
Toast.makeText(this, s, Toast.LENGTH_SHORT).show();
mTv.setText(s);
}
}
Activity現(xiàn)在要做的就是兩件事缓溅,首先你要new 一個(gè)IPresenter出來蛇损,然后findviewbyid就行了,其他的都交給Presenter就行了。