MVP设计模式嵌入百度地图小结

2016-09-09 22:26 评论 0 条

摘要

公司需要对已上线的APP进行组织架构的调整,看着一个类里面1000+甚至2000+的代码,有种摸不着头脑的感觉。对设计模式一窍不通的我,这两天在学习如何能够有效分离同一个类的代码量,于是看了MVC/MVP/MVVM的设计模式,在此之前只懂得一点点MVC设计模式,但没法解决Activity或Fragment类代码臃肿的问题,然后看了MVP和MVVM的设计思路,MVP是最适合重构当前已上线APP的设计模式。

一.什么是MVP?

百度搜索MVP设计模式,找到很多MVP文字介绍的文章,看了那么多篇的文章,文字怎么描述MVP的定义TeachCourse的确记不住了,唯一还有印象的是描述MVP的Demo,开发的步骤:

1、建立bean

  1. public class UserBean {  
  2.     private String mFirstName;  
  3.     private String mLastName;  
  4.     public UserBean(String firstName, String lastName) {  
  5.         this. mFirstName = firstName;  
  6.         this. mLastName = lastName;  
  7.     }  
  8.     public String getFirstName() {  
  9.         return mFirstName;  
  10.     }  
  11.     public String getLastName() {  
  12.         return mLastName;  
  13.     }  
  14. }  

2、建立model接口(处理业务逻辑,这里指数据读写)

  1. public interface IUserModel {  
  2.     void setID(int id);  
  3.     void setFirstName(String firstName);  
  4.     void setLastName(String lastName);  
  5.     int getID();  
  6.     UserBean load(int id);// 通过id读取user信息,返回一个UserBean  
  7. }  

3、建立view接口(更新ui中的view状态),这里列出需要操作当前view的方法

  1. public interface IUserView {  
  2.     int getID();  
  3.     String getFristName();  
  4.     String getLastName();  
  5.     void setFirstName(String firstName);  
  6.     void setLastName(String lastName);  
  7. }  

4、建立presenter(主导器,通过iView和iModel接口操作model和view),activity可以把所有逻辑给presenter处理,这样java逻辑就从手机的activity中分离出来

  1. public class UserPresenter {  
  2.     private IUserView mUserView;  
  3.     private IUserModel mUserModel;  
  4.     public UserPresenter(IUserView view) {  
  5.         mUserView = view;  
  6.         mUserModel = new UserModel();  
  7.     }  
  8.     public void saveUser( int id, String firstName, String lastName) {  
  9.         mUserModel.setID(id);  
  10.         mUserModel.setFirstName(firstName);  
  11.         mUserModel.setLastName(lastName);  
  12.     }  
  13.     public void loadUser( int id) {  
  14.         UserBean user = mUserModel.load(id);  
  15.         mUserView.setFirstName(user.getFirstName()); // 通过调用IUserView的方法来更新显示  
  16.         mUserView.setLastName(user.getLastName());  
  17.     }  
  18. }  

5、UserActivity实现了IUserView及View.OnClickListener接口,同时有一个UserPresenter成员变量:

  1. public class UserActivity extends Activity implements OnClickListener ,  
  2.              IUserView {  
  3.    
  4.        private EditText mFirstNameEditText , mLastNameEditText , mIdEditText ;  
  5.        private Button mSaveButton , mLoadButton ;  
  6.        private UserPresenter mUserPresenter ;  
  7. ...  
  8.   
  9.        }  

重写了OnClick方法:

  1. @Override  
  2. public void onClick(View v) {  
  3.        // TODO Auto-generated method stub  
  4.        switch ( v. getId()) {  
  5.        case R .id .saveButton :  
  6.        mUserPresenter .saveUser (getID (), getFristName (),  
  7.                getLastName ());  
  8.        break ;  
  9.        case R .id .loadButton :  
  10.        mUserPresenter .loadUser (getID ());  
  11.        break ;  
  12.        default :  
  13.        break ;  
  14.      }  
  15. }  

这属于MVP设计模式其中的一个Demo,因为不止在一篇文章里看到,自然对它的实现思路了解清楚,MVP属于MVC模式的升级版,即Module,View,Presenter,在一个完整的MVP例子中划分成四个部分:BeanModule(IModule,IModuleImpl)Presenter(IPresenter,IPresenterImpl)View(Activity或Fragment),是否了解接口的使用和定义方法决定你是否理解四大部分的意义,如果未阅读过《你会错过的接口理解三部曲:定义,设置和实现》这篇文章的童鞋,建议先熟悉一下接口的使用或者点击“搜索”按钮,输入“接口”查找,阅读更多相关文章。

PS:学习一种设计模式,对于新手来说先了解设计模式的实现过程,比你直接阅读概念文字容易理解一点,然后根据实现的思路结合到Project Develop中,是快速掌握知识的一种方式,下面由浅入深说明怎么在Android Project中使用MVP。在一个设计模式使用过程根据项目的具体情况,会有所区别,比如:上面的Demo,可能在代码量很多的时候,会分别多创建IUserModelImpl实现类、IUserPresenter接口,然后在实现类中完成功能的封装,通过IUserView接口在Activity或Fragment类中处理结果,思路就是将一个类的代码分离,有一种各司其职的感觉,最后将结果反馈给boss,让boss做最后的决策。

二.MVP开发百度地图Demo(AS开发工具)

使用百度地图,第一步使用百度账号申请百度地图密钥,第二步下载百度地图jar包添加到libs文件夹中,第三步配置build.gradle文件,在build.gradle文件的android标签内指定jniLibs的路径

  1. sourceSets {  
  2.         main {  
  3.             jniLibs.srcDir 'libs'  
  4.         }  
  5. }  

否则报错,java.lang.UnsatifiedLinkError:Native method not found:com.baidu.platform.comjni.map.commonmemcache.JNICommonMemCache.Create,也可以将libs存放so包的文件夹(arm64-v8a/armeabi/armeabi-v7a/x86/x86_64)放置在src/main/jniLibs文件夹内,这时候不需要配置build.gradle指定jniLibs的路径。

实现的功能,在百度地图动态加载图层,需要用到的数据是各个图层的经纬度信息,实现的思路:
002-mvp-android-design-img

1、IRecycleModule和IRecycleModuleImpl生成经纬度数据信息

  1. /** 
  2.  * Created by postmaster@teachcourse.cn on 2016/9/9. 
  3.  */  
  4. public class IRecycleModuleImpl implements IRecycleModule {  
  5.     @Override  
  6.     public List<LatLng> getLatLng() {  
  7.   
  8.         List<LatLng> list = new ArrayList<LatLng>();  
  9.   
  10.         list.add(dealLatLng(113.277521,23.12155));  
  11.         list.add(dealLatLng(113.276614,23.124774));  
  12.         list.add(dealLatLng(113.27612,23.123087));  
  13.         list.add(dealLatLng(113.277638,23.123436));  
  14.         list.add(dealLatLng(113.277188,23.121658));  
  15.   
  16.         return list;  
  17.     }  
  18.   
  19.     /** 
  20.      * 经度值大于纬度,注意构造方法:LatLng(double latitude,double longitude) 
  21.      * @param longitude 
  22.      * @param latitude 
  23.      * @return 
  24.      */  
  25.     private LatLng dealLatLng(double longitude,double latitude){  
  26.            return new LatLng(latitude,longitude);  
  27.     }  
  28. }  

2、IRecycleView在百度地图显示图层内容

  1. /** 
  2.  * Created by postmaster@teachcourse.cn on 2016/9/9. 
  3.  */  
  4. public interface IRecycleView {  
  5.     void displayIcon(OverlayOptions overlayOptions);  
  6. }  

在IRecyclePresent的IRecyclePresenterImpl实现方法中调用:

  1. mIRecycleView.displayIcon(ooA);  

在MainActivity中实现:

  1. @Override  
  2. public void displayIcon(OverlayOptions overlayOptions) {  
  3.         mMap.addOverlay(overlayOptions);  
  4. }  

3、IRecyclePresenter和IRecyclePresenterImplements生成百度图层

  1. /** 
  2.  * Created by postmaster@teachcourse.cn on 2016/9/9. 
  3.  */  
  4. public class IRecyclePresenterImpl implements IRecyclePresenter {  
  5.     private IRecycleView mIRecycleView;  
  6.     private Context mContext;  
  7.   
  8.     public IRecyclePresenterImpl(IRecycleView mIRecycleView, Context mContext) {  
  9.         this.mIRecycleView = mIRecycleView;  
  10.         this.mContext = mContext;  
  11.     }  
  12.   
  13.     @Override  
  14.     public void dynamicProductIcon() {  
  15.         final View markView = LayoutInflater.from(mContext).inflate(  
  16.                 R.layout.bad_things_bg, null);  
  17.         ImageView img = (ImageView) markView.findViewById(R.id.marker_view_bg);  
  18.         Bitmap map = BitmapFactory.decodeResource(mContext  
  19.                 .getResources(), R.drawable.icon_marka_bad);  
  20.         img.setImageBitmap(map);  
  21.         BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory  
  22.                 .fromView(markView);  
  23.         IRecycleModule module=new IRecycleModuleImpl();  
  24.         for (LatLng latLng:module.getLatLng()){  
  25.             OverlayOptions ooA = new MarkerOptions().position(latLng).icon(bitmapDescriptor);  
  26.             mIRecycleView.displayIcon(ooA);  
  27.         }  
  28.     }  
  29. }  

PS:在百度地图显示图标的时候,需要注意LatLng这个类,该类构造方法传入的参数,前者是纬度,后者是经度,百度拾取坐标系统获取的数值:经度,纬度,所以定义了dealLatLng()方法处理,否则地图显示空白。

003-baidu-map-mvp-icon

设计的过程,通常是变化的,在百度地图添加图标的例子中,详细划分MVP设计模式为接口和实现类,可能在有的时候直接定义接口,具体实现放在IRecyclePresenterImpl类实现IRecycleModule,现在独立出来一个IRecycleModuleImpl;同时记住一个原则,Activity或Fragment负责更新View视图,Presenter负责处理逻辑,IRecycleView负责反馈Presenter处理结果给Activity或Fragment,IRecycleModule负责操作数据内容。按照MVP这样的设计模式,你会发现Activity或Fragment类的代码量有效分离,是不是很爽。

推荐阅读:

深入理解接口的定义和意义(2)之MVP实例

当前文章价值0.09元,扫一扫支付后添加微信提供帮助!(如不能解决您的问题,可以申请退款)

你可能感兴趣的文章

来源:每日教程每日一例,深入学习实用技术教程,关注公众号TeachCourse
转载请注明出处: https://www.teachcourse.cn/2034.html ,谢谢支持!

资源分享

分类:Android 标签:,
php7.0-fpm启动启动异常 php7.0-fpm启动启动异常
Android资源目录res多个限定符结合使用示例介绍 Android资源目录res多个限定符结
盘点2018年,那些做过的事情 盘点2018年,那些做过的事情
十一种错误的避孕观念 十一种错误的避孕观念

发表评论

呲牙 憨笑 坏笑 偷笑 色 微笑 抓狂 睡觉 酷 流汗 鼓掌 大哭 可怜 疑问 晕 惊讶 得意 尴尬 发怒 奋斗 衰 骷髅 啤酒 吃饭 礼物 强 弱 握手 OK NO 勾引 拳头 差劲 爱你

表情