MVP模式

前言

MVP是一种MVC的变形,相比MVC它大大减少了Activity的责任将主要的逻辑操作集中在Presenter层中,从而使得MVP的代码结构变得更清晰。

MVP结构

MVP主要由Model、View、Presenter三部分构成。
Model:负责数据的处理,即数据的获取、存储、解析、分发、修改等操作;
View:即Activity和Fragment,负责页面的绘制,刷新;
Presenter:负责连接Model层和View层,从Model中获取数据然后控制View刷新页面,是主要逻辑操作的地方。

这里借用此文的一张图片来表示Model、View和Presenter三者的关系
mvp

MVP案例

这是一个简单的菜谱App,主要包括列表和详情,下面以列表页威力展示一下MVP的运用。

列表页视图:
App

项目结构:
object

(1)Model层
这里的Model主要负责从网络获取数据

public interface ITypeListModel {
    void loadList(String url, Map<String,String> paraMap, TypeListListener listener);
    void cancle();

    interface TypeListListener{
        void loadSuccess(String json,Map<String,String> hMap);
        void loadFail(Exception e,Map<String,String> hMap);
    }
}
public class TypeListModel implements ITypeListModel {

    private RequestCall call;

    @Override
    public void loadList(String url, final Map<String, String> paraMap, final ITypeListModel.TypeListListener listener) {
        call= OkHttpUtils.post()
                .url(url)
                .params(paraMap)
                .build();
        call.execute(new StringCallback() {
            @Override
            public void onError(Call call, Exception e, int id) {
                listener.loadFail(e,paraMap);
            }

            @Override
            public void onResponse(String response, int id) {
                listener.loadSuccess(response,paraMap);
            }
        });
    }

    @Override
    public void cancle() {
        if(call!=null)
            call.cancel();
    }
}

(2)View层
View层管理点击页面上控件的状态和控件的点击事件
我将View和Presenter的两个接口都放在了Contract中方便管理

    interface View{

        void showLoading();

        void hideLoading();

        void showLoadFail();

        void hideLoadFail();

        void showContent();

        void hideContent();

        void toastMessage(String message);

        void setContentData(List<FoodTypeGroup> list);

    }
public class FoodTypeActivity extends AppCompatActivity implements FoodTypeContract.View, View.OnClickListener, ExpandableListView.OnChildClickListener {

    @Bind(R.id.tv_head_back)
    View tvBack;
    @Bind(R.id.tv_head_title)
    TextView tvTitle;
    @Bind(R.id.elv_content)
    ExpandableListView elvContent;
    @Bind(R.id.progressBar)
    View progressBar;
    @Bind(R.id.tv_fail)
    View tvFail;

    private FoodTypeAdapter adapter;
    private List<FoodTypeGroup> adapterList;
    private FoodTypeContract.Presenter foodTypePresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_food_type);
        ButterKnife.bind(this);
        foodTypePresenter=new FoodTypePresenter(this);
        initView();
        initAdapter();
        foodTypePresenter.start();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        foodTypePresenter.onDestroy();
    }

    private void initView() {
        tvBack.setVisibility(View.GONE);
        tvTitle.setText("菜品分类");
        tvFail.setOnClickListener(this);
        elvContent.setOnChildClickListener(this);
    }

    private void initAdapter(){
        adapterList=new ArrayList<>();
        adapter=new FoodTypeAdapter(this,adapterList);
        elvContent.setAdapter(adapter);
    }


    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.tv_fail://重新加载
                foodTypePresenter.start();
                break;
        }
    }

    @Override
    public boolean onChildClick(ExpandableListView expandableListView, View view, int i, int i1, long l) {
        Intent intent=new Intent(this,TypeListActivity.class);
        intent.putExtra("id",adapterList.get(i).getList().get(i1).getId());
        intent.putExtra("type",adapterList.get(i).getList().get(i1).getName());
        startActivity(intent);
        return true;
    }

    @Override
    public void showLoading() {
        progressBar.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideLoading() {
        progressBar.setVisibility(View.GONE);
    }

    @Override
    public void showLoadFail() {
        tvFail.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideLoadFail() {
        tvFail.setVisibility(View.GONE);
    }

    @Override
    public void showContent() {
        elvContent.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideContent() {
        elvContent.setVisibility(View.GONE);
    }

    @Override
    public void toastMessage(String message){
        ToastUtil.showToast(this,message);
    }

    @Override
    public void setContentData(List<FoodTypeGroup> list) {
        adapterList.clear();
        adapterList.addAll(list);
        adapter.notifyDataSetChanged();
    }
}

(3)Presenter层
从View中接收到获取列表请求后调用Model获取列表数据,根据列表数据的状态控制View作不同的显示

    interface Presenter extends BasePresenter{
        @Override
        void start();

        @Override
        void onDestroy();
    }
public class FoodTypePresenter implements FoodTypeContract.Presenter{
    private FoodTypeContract.View foodTypeView;
    private IFoodTypeModel iFoodTypeModel;
    public FoodTypePresenter(FoodTypeContract.View foodTypeView){
        this.foodTypeView=foodTypeView;
        iFoodTypeModel=new FoodTypeModel();
    }

    @Override
    public void start() {
        foodTypeView.hideContent();
        foodTypeView.hideLoadFail();
        foodTypeView.showLoading();
        final Map<String,String> paraMap=new HashMap<>();
        paraMap.put("key",BaseUrl.KEY);
        iFoodTypeModel.loadList(BaseUrl.FOODTYPE, paraMap, new IFoodTypeModel.FoodTypeListener() {
            @Override
            public void loadSuccess(String json) {
                LoadSuccess.onSuccess(json, new LoadSuccess.LoadSuccessCallBack() {
                    @Override
                    public void code200(JSONObject json) throws JSONException {
                        if(foodTypeView!=null) {
                            List<FoodTypeGroup> list = JSON.parseArray(json.getJSONArray("result").toString(), FoodTypeGroup.class);
                            foodTypeView.hideLoading();
                            foodTypeView.showContent();
                            foodTypeView.setContentData(list);
                        }
                    }
                    @Override
                    public void codeOther(String errorMessage) {
                        if(foodTypeView!=null) {
                            foodTypeView.hideLoading();
                            foodTypeView.showLoadFail();
                            foodTypeView.toastMessage(errorMessage);
                        }
                    }
                });
            }

            @Override
            public void loadFail(Exception e) {
                L.e("NET",e.getMessage());
                if (foodTypeView!=null) {
                    foodTypeView.hideLoading();
                    foodTypeView.showLoadFail();
                    foodTypeView.toastMessage("网络连接异常");
                }
            }
        });
    }

    @Override
    public void onDestroy(){
        iFoodTypeModel.cancle();
        foodTypeView=null;
    }

}

项目地址

https://github.com/NevLight/Fish

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值