Android APP架构的那点事儿[MVP架构搭建]
2016-02-28 11:40
489 查看
接上篇《APP架构的那点事儿[网络模块]》
完成了网络模块,那么我们是不是该进入MVP主体架构的开发了,当然,有些朋友会说:“难道一定要先写网络模块,就不能先做架构主体么!” 这个随意了,看个人喜好,有话好好说嘛,把砖头放下.
所谓的mvp,个人理解为model层处理业务逻辑(主要是数据读写、与服务器端通信(其实也是读写数据));view层处理ui显示(通常包含Activity、Fragment、View (应该如何选择));presenter层为指示器,应该说包含很多个Presenter组成,作为中间件操作相对应的model和view)
具体MVP细节,感兴趣的朋友搜下,很多!
如何下手开发?其实我们可以从一个简单的功能点入手,然后其他功能照着模子继续造轮子就行。下面简单一个获取城市列表的例子。
解释一下,Fragment的英译是”碎片”,Fragment是Activity的封装部件,简单说Fragment要基于Activity才能显示,View也一样。当Activity太大,承载太多不同功能或类型的UI的时候,可以尝试拆分为独立的多个独立的Fragment(或View)来显示UI。而Activity和Fragment是有生命周期的结构使用两者,保持职责清晰,心里要有个概念,那就是单一原则。
完成了网络模块,那么我们是不是该进入MVP主体架构的开发了,当然,有些朋友会说:“难道一定要先写网络模块,就不能先做架构主体么!” 这个随意了,看个人喜好,有话好好说嘛,把砖头放下.
所谓的mvp,个人理解为model层处理业务逻辑(主要是数据读写、与服务器端通信(其实也是读写数据));view层处理ui显示(通常包含Activity、Fragment、View (应该如何选择));presenter层为指示器,应该说包含很多个Presenter组成,作为中间件操作相对应的model和view)
具体MVP细节,感兴趣的朋友搜下,很多!
如何下手开发?其实我们可以从一个简单的功能点入手,然后其他功能照着模子继续造轮子就行。下面简单一个获取城市列表的例子。
Model层
/** * 城市对象模型 * Created by liaonaibo on 16/2/14. */ public class City extends BaseResource{ /**城市ID*/ public int id; /**省份名称*/ public String province; /**城市*/ public String city; /**城市/区名称*/ public String district; public City(){ this.dataType = DataType.DT_List_City_Weather; } public static List<City> parserList(String json){ try { JSONObject obj = new JSONObject(json); String data = obj.optString("result"); if (!TextUtils.isEmpty(data)) { List<City> list = new Gson().fromJson(data, new TypeToken<List<City>>() { }.getType()); return list; } } catch (Exception e) { e.printStackTrace(); } return null; } }
Presenter层
/** * 城市列表UI主持者 * 作为View与Model交互的中间纽带,处理与用户交互的负责逻辑 * Created by liaonaibo on 16/2/15. */ public class CityListPresenter { private Context mContext; private ICityListView mICityListView; private boolean isLoading; private List<BaseResource> mData; public CityListPresenter(Context context,ICityListView iCityListView){ this.mContext = context; this.mICityListView = iCityListView; this.mData = new ArrayList<BaseResource>(); } public void getData(){ if (isLoading){ return; } isLoading = true; //通知UI数据加载中 mICityListView.onDataLoading(); NetworkController.getInstance(mContext).requestCityList(null, new NetworkRequestListener() { @Override public void response(String response) { isLoading = false; if(!TextUtils.isEmpty(response)){ List<City> list = City.parserList(response); if(null != list && list.size() > 0){ mData.addAll(list); //显示数据到UI上 mICityListView.showCityList(mData); }else{ //没有数据了 mICityListView.requestDataFailByNoData(); } } } @Override public void error(int errorCode, String errorLog) { isLoading = false; //通知UI网络异常 mICityListView.requestDataFailByNetswork(); } }); } /** * 跳转到天气详情界面 * @param view */ public void jumpToWeatherDetailActivity(View view) { Object object = view.getTag(); if(null != object){ City city = (City) object; WeatherDetailActivity.start(mContext, city); } } /** * 获取点击事件数组 * @return */ public View.OnClickListener[] getOnClickListeners() { View.OnClickListener[] listeners = new View.OnClickListener[1]; listeners[0] = new View.OnClickListener() { @Override public void onClick(View v) { jumpToWeatherDetailActivity(v); } }; return listeners; } /** * 搜索城市 * @param cityName */ public void searchCity(String cityName) { City city = new City(); city.dataType = DataType.DT_List_City_Search; city.city = cityName; WeatherDetailActivity.start(mContext, city); } }
View层
个人总结,对于View所需定义的接口,可以通过产品功能上的入手,熟悉产品交互流程, 然后考虑:该操作需要什么?(那些参数?) 该操作的结果,对应的反馈?(显示列表??showFailedError?) 该操作过程中对应的友好的交互?(加载中?加载完成?)
/** * 城市列表View接口 * Created by liaonaibo on 16/2/15. */ public interface ICityListView { /**显示城市列表*/ void showCityList(List<BaseResource> list); /**数据加载中*/ void onDataLoading(); /**没有数据*/ void requestDataFailByNoData(); /**请求失败*/ void requestDataFailByNetswork(); }
/** * 城市列表界面 */ public class MainActivity extends FragmentActivity implements ICityListView, View.OnClickListener { private CityAdapter mAdapter; private ListView mListView; private ProgressBar mProgressBar; private EditText et_search; private CityListPresenter mPresenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initVariable(); initLayout(); loadData(); } /** * 初始化变量 */ private void initVariable() { mPresenter = new CityListPresenter(this, this); } /** * 初始化布局 */ private void initLayout() { mListView = (ListView) findViewById(R.id.activity_main_lv); mProgressBar = (ProgressBar) findViewById(R.id.activity_main_pb); et_search = (EditText) findViewById(R.id.activity_main_et_search); et_search.setOnEditorActionListener(new TextView.OnEditorActionListener() { public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_SEARCH || (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) { searchCity(); return true; } return false; } }); findViewById(R.id.activity_main_iv_search).setOnClickListener(this); } /** * 加载数据 */ private void loadData() { //调用主持者获取数据 mPresenter.getData(); } @Override public void showCityList(List<BaseResource> list) { mProgressBar.setVisibility(View.GONE); if (null == mAdapter) { mAdapter = new CityAdapter(this, mPresenter, list); mListView.setAdapter(mAdapter); } else { mAdapter.notifyDataSetChanged(); } } @Override public void onDataLoading() { //TODO:数据加载中 mProgressBar.setVisibility(View.VISIBLE); } @Override public void requestDataFailByNoData() { //TODO:没有数据了 mProgressBar.setVisibility(View.GONE); Toast.makeText(this, "没有数据了,稍候重试", Toast.LENGTH_SHORT).show(); } @Override public void requestDataFailByNetswork() { //网络异常 mProgressBar.setVisibility(View.GONE); Toast.makeText(this, "网络异常,稍候重试", Toast.LENGTH_SHORT).show(); } @Override public void onClick(View v) { int id = v.getId(); if (R.id.activity_main_iv_search == id) { searchCity(); } } private void searchCity() { String city = et_search.getText().toString(); if (TextUtils.isEmpty(city)) { Toast.makeText(this, "请输入城市名称", Toast.LENGTH_SHORT).show(); return; } mPresenter.searchCity(city); } }
如何选择使用Activity、Fragment、View?
有朋友问,项目应该使用Activity还是Fragment还是View?首先我们要理解这三者的关系解释一下,Fragment的英译是”碎片”,Fragment是Activity的封装部件,简单说Fragment要基于Activity才能显示,View也一样。当Activity太大,承载太多不同功能或类型的UI的时候,可以尝试拆分为独立的多个独立的Fragment(或View)来显示UI。而Activity和Fragment是有生命周期的结构使用两者,保持职责清晰,心里要有个概念,那就是单一原则。
相关文章推荐
- 个人信息安全报告发布:有 APP 每分钟调用位置权限 1468 次
- 下载量超过一亿的流行应用被发现含有恶意模块
- 苹果与Siri的七年之痒:“宫斗”戏码不断上演
- 架构纵横谈之二 ---- 架构的模式与要点
- BS项目中的CSS架构_仅加载自己需要的CSS
- 关于三种主流WEB架构的思考
- APP添加CNZZ统计插件教程 Android版添加phonegap
- Android操作系统的架构设计分析
- w3c技术架构介绍
- linux学习笔记 linux目录架构
- Android APP与媒体存储服务的交互
- ASP.NET小结之MVC, MVP, MVVM比较以及区别(一)
- java实现收藏名言语句台词的app
- 修改Android App样式风格的方法
- Android App数据格式Json解析方法和常见问题
- 浅析MVP模式中V-P交互问题及案例分享
- 通过Html网页调用本地安卓(android)app程序代码
- 百度地图API提示230 错误app scode码校验失败的解决办法
- js判断移动端是否安装某款app的多种方法