最近要开发个新项目,原公司好几个项目,老板说要合并在一个项目里;苦逼啊,原来的项目经过好几拨人下过手了,已经是烂坟岗了,不忍下眼了 啊。
就想着要不要搞个MVP,周末来个朋友,聊了一下,早上来公司撸了个demo,放在这做个笔记。
下面直接上代码:(mvp模式,我就不作解释了,可以参考这个链接:http://kb.cnblogs.com/page/137392/)
本Demo是查询手机号归属地,接口用的是juhe免费接口;
效果就是这样,ui比较丑:
Demo逻辑很简单,就是输入手机号查询手机的归属地和运营商,点击个Button 然后向服务器请求数据,拿到数据展示结果;
目录结构:
activity:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_mvp_demo); ButterKnife.bind(this); mDemoActivityP = new MvpDemoActivityP(this, this); 构造presenter对象 } @OnClick(R.id.btn_search) public void onViewClicked() { //TODO 查询 doSearch(); } /** * 开始查询 */ private void doSearch() { String phone = demoTest.getText().toString(); mDemoActivityP.commitPhone(phone, key);//Presenter与具体的View是没有直接关联的,//而是通过定义好的接口进行交互 } /** * 查询结果处理--通知用户 * @param commitBean */ @Override public void sucess(PhoneAddressBean commitBean) { Toast.makeText(this, "查询成功", Toast.LENGTH_SHORT).show(); textcontent.setText("归属地:" + commitBean.getResult().getProvince() + ", 运营商:" + commitBean.getResult().getCompany()); } /** * 查询失败处理--通知用户 * @param error */ @Override public void failed(RetrofitError error) { //TODO 通知用户查询失败 } @Override public void OhterError(String string) { Toast.makeText(this, string, Toast.LENGTH_SHORT).show(); }
构造一个presenter 通过presenter确定使用哪个model处理数据;
点击查询按钮,调用presenter中的查询方法进行查询。
核心: doSearch()方法,发起查询,这个时候presenter上场了,事先在presenter中定义好处理的方法,在view层由构造的presenter对象调用。
view层接口:
public interface MvpDemoActivityI<T> { void sucess(T t);//查询成功 void failed(RetrofitError error);//查询失败 void OhterError(String string);//其他异常 }
presenter中的逻辑处理:
验证输入手机号的合法性,不合法通过接口通知view(OtherError(String str)),告诉用户输入有误,提醒用户重新输入。是合法数据,则调用model进行数据查询请求(网络访问服务器);
拿到服务器响应json回掉通知presenter,再由presenter去通知view层更新(或通知用户)model与presenter之间也是通过接口进行通信。
public class MvpDemoActivityP { public Context context; private Context mContext; MvpDemoActivityI mvpDemoActivityI; MVPModel mvpModel; public MvpDemoActivityP(MvpDemoActivityI mvpDemoActivityI, Context context) { this.mvpDemoActivityI = mvpDemoActivityI; this.mvpModel = MVPModel.getHttpUtils(context);//构造model对象,由该对象发起model交互连线 } /** * presenter和model的交互 * @param phone * @param key */ public void commitPhone(String phone, String key) { boolean isEm = Utils.getmUtils(context).isEmpty(phone); if (!isEm) { boolean b = Utils.getmUtils(context).isMobileNO(phone); if (b) { mvpModel.commit(phone, key, new ModelI<PhoneAddressBean>() { @Override public void sucess(PhoneAddressBean commitBean) { //TODO 通知页面更新 mvpDemoActivityI.sucess(commitBean);//presenter和view事先约定好的接口 } @Override public void failed(RetrofitError error) { mvpDemoActivityI.failed(error);//presenter和view事先约定好的接口 } }); } else { mvpDemoActivityI.OhterError("格式非法,输入正确手机号");//格式非法,输入正确手机号,//presenter和view事先约定好的接口
} } else { mvpDemoActivityI.OhterError("输入正确的手机号");//presenter和view事先约定好的接口
} }}
model:
这里网络请求,我 用的是Retorfit.接口主要的作用就是把请求结果传给presenter。
/** * 网络请求数据,该方法为上传用户当前的经纬度 * @param phone * @param mmodelI */ public void commit(String phone,String key , final ModelI mmodelI) { mDemoI.SearchPhone(phone, key, new Callback<PhoneAddressBean>() { @Override public void success(PhoneAddressBean commitBean, Response response) { mmodelI.sucess(commitBean);//接口回调给presenter } @Override public void failure(RetrofitError error) { mmodelI.failed(error); } }); }
底层的网络请求接口: 这里使用的是Retrofit网络框架来请求服务器数据
public interface MvpDemoI { //1.最后调用请求模板接口的方法. 参数放到一个集合中 @GET("/mobile/get") public void SearchPhone(@Query("phone") String phone, @Query("key") String key,Callback<PhoneAddressBean> t); }
总结: mvp 中主要是通过接口实现view与model的数据传输,view不与model之间关联,而是通过presenter中的接口。model与presenter也是通过约定的接口传输处理结果;demo中有的地方使用到泛型,有的没有。正常开发最好还是设为泛型,封装成工具,避免代码臃肿多余。我就懒得改了。拖了几天,发到这记着。
demo中有什么不正确的地方,大神们轻喷。