Android APP架构的那点事儿[MVP架构搭建]

来源:互联网 发布:sai for mac 有压感 编辑:程序博客网 时间:2024/06/06 05:02

接上篇《APP架构的那点事儿[网络模块]》

完成了网络模块,那么我们是不是该进入MVP主体架构的开发了,当然,有些朋友会说:“难道一定要先写网络模块,就不能先做架构主体么!” 这个随意了,看个人喜好,有话好好说嘛,把砖头放下.

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?首先我们要理解这三者的关系

Activity、fragment、view三者关系

解释一下,Fragment的英译是”碎片”,Fragment是Activity的封装部件,简单说Fragment要基于Activity才能显示,View也一样。当Activity太大,承载太多不同功能或类型的UI的时候,可以尝试拆分为独立的多个独立的Fragment(或View)来显示UI。而Activity和Fragment是有生命周期的结构使用两者,保持职责清晰,心里要有个概念,那就是单一原则。

0 0
原创粉丝点击