MVP+Databinding模式开发APP(二)

原创 2017年01月03日 11:02:07

前言:上篇文章MVP+Databinding模式开发APP(一) 讲述的文章因为UI框架不需要访问网络所以没有用到Model,所以未能完全的体现MVP的价值。下面来进入第二部分例子。

什么是MVC?
Model:从网络上获取的数据、数据库等数据结构
View:XML
Controller:Activity\Fragment。Activity\Fragment不仅需要设置数据、展示数据还得处理用户的事件逻辑、再与Model交互。这样在复杂逻辑的页面下Acitvity或Fragment十分的臃肿,并且耦合太高,不利用后期的维护。

什么是MVP?
MVP是MVC的升级,MVP把MVC的Model层和View层分离,达到解耦的目的,并且减轻了Activity\Fragment压力,把所有的业务逻辑交给P层处理。View层只负责界面展示。代码结构会变成异常的清晰,维护成本大大降低。

预览图
这里写图片描述

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
   >

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipe_refresh_widget"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ListView
            android:id="@+id/listview_square"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            >

        </ListView>

    </android.support.v4.widget.SwipeRefreshLayout>


</layout>

SwipeRefreshLayout下拉刷新是谷歌自带的,在V4包下。

//用户访问数据成功时回调的接口。
public interface OnHttpCallBack<T> {

    void onSuccess(T data);
    void onFail(String error);
}

public class SquareContract {

    public interface ISquareModel {
        //获得轮播图的数据
        void getHeaderData(OnHttpCallBack<AdvertisementsBean> callBacK);
        //获得主体列表的数据
        void getContentData(OnHttpCallBack<SubjectPiazzaModel> callBacK);
    }

    public interface ISquareView {
        //隐藏下拉刷新进度条
        void hideProgress();
        //显示服务器异常提示框
        void showServerErrorMsg();
        //跳转到类型列表
        void toTypeTopicList();
        //跳转到话题详情
        void toTopicDetail();
        //显示无网络错误信息
        void showErrorMsg();
        //刷新轮播图数据
        void refreshCircleData(ArrayList<String> imageDescList, ArrayList<String> urlList);
        //刷新主列表数据
        void refreshContentData(List<SubjectPiazzaModel.ColumnOverview> columnOverviews);

    }

    public interface ISquarePresenter {
        //获得轮播图的数据,并在此方法中处理轮播图的业务逻辑
        void getHeaderData();
        //获得主体列表的数据,并在此方法中处理主体列表的业务逻辑
        void getContentData();
    }
}

M 、V、P三层的接口都在这里,并且附上详细的说明。

public class SquareFragment extends BaseFragment implements SquareContract.ISquareView{

    private FragmentSquareBinding squareBinding;
    private SquarePresenter squarePresenter;
    private List<SubjectPiazzaModel.ColumnOverview> columnOverviews;
    private CirclePagerBinding pagerBinding;
    private SquareAdapter squareAdapter;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        squareBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_square,container,false);
        init();
        initData();
        setListener();
        return squareBinding.getRoot();
    }

    @Override
    public void init() {
        squarePresenter = new SquarePresenter(this);
    }

    @Override
    public void initData() {

        //初始化listView
        columnOverviews=new ArrayList<>();
        squareAdapter = new SquareAdapter(columnOverviews);
        squareBinding.listviewSquare.setAdapter(squareAdapter);

        //初始化轮播图
        pagerBinding = DataBindingUtil.inflate(LayoutInflater.from(getActivity()), R.layout.circle_pager,null,false);
        squareBinding.listviewSquare.addHeaderView(pagerBinding.cycleView);

        //首次进入访问网络
        squarePresenter.getHeaderData();
        squarePresenter.getContentData();
    }

    @Override
    public void setListener() {
        //手指触摸下滑时触发
        squareBinding.swipeRefreshWidget.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                //刷新数据
                squarePresenter.getHeaderData();
                squarePresenter.getContentData();
            }
        });

    }


    @Override
    public void hideProgress() {
        //关闭下拉刷新
        squareBinding.swipeRefreshWidget.setRefreshing(false);
    }

    @Override
    public void refreshCircleData(ArrayList<String> imageDescList, ArrayList<String> urlList) {

        ImageCycleView.ImageCycleViewListener mAdCycleViewListener = new ImageCycleView.ImageCycleViewListener() {

            @Override
            public void onImageClick(int position, View imageView) {
            }

            @Override
            public void displayImage(String imageURL, ImageView imageView) {
                /** 在此方法中,显示图片,可以用自己的图片加载库,也可以用本demo中的(Imageloader) */
                ImageLoaderHelper.getInstance().loadImage(imageURL, imageView);
            }
        };
        /** 设置轮播图数据 */
        pagerBinding.cycleView.setImageResources(imageDescList, urlList, mAdCycleViewListener);
        pagerBinding.cycleView.startImageCycle();
    }

    @Override
    public void refreshContentData(List<SubjectPiazzaModel.ColumnOverview> columnOverviews) {
        this.columnOverviews.clear();
        this.columnOverviews.addAll(columnOverviews);
        squareAdapter.notifyDataSetChanged();
    }


    @Override
    public void toTypeTopicList() {
        Intent intent=new Intent(getActivity(),TopicListActivity.class);
        startActivity(intent);
    }

    @Override
    public void toTopicDetail() {
        Intent intent=new Intent(getActivity(),DetailTopicActivity.class);
        startActivity(intent);
    }

    @Override
    public void showErrorMsg(){
        Snackbar.make(squareBinding.getRoot(),"网络不给力,请检查网络后重试!",2500).show();
    }
    @Override
    public void showServerErrorMsg(){
        Snackbar.make(squareBinding.getRoot(),"服务器异常,请联系管理员!",2500).show();
    }
public class SquarePresenter implements SquareContract.ISquarePresenter{

    private final SquareContract.ISquareView iSquareView;
    private final SquareModel squareModel;

    public SquarePresenter(SquareContract.ISquareView squareView){
        iSquareView =squareView;
        //初始化对应的Model
        squareModel = new SquareModel();
    }

    @Override
    public void getHeaderData( ) {
        squareModel.getHeaderData(new OnHttpCallBack<AdvertisementsBean>() {

            @Override
            public void onSuccess(AdvertisementsBean data) {
                //如果返回的状态码为成功再解析数据
                if(data.errCode.equals(Constant.SUCCESS_CODE)){
                    //轮播图的描述
                    ArrayList<String> imageDescList=new ArrayList<String>();
                    //轮播图的图片URL地址
                    ArrayList<String> urlList=new ArrayList<String>();
                    List<AdvertisementsBean.Advertisement> advertisements = data.result.advertisements;
                    urlList.clear();
                    //循环装载数据进入List
                    for (int i = 0; i < advertisements.size(); i++) {
                        urlList.add(advertisements.get(i).coverUrl);
                        imageDescList.add(advertisements.get(i).description);
                    }
                    //把数据设置给轮播图
                    iSquareView.refreshCircleData(imageDescList, urlList);
                }
                //如果返回不是成功的状态码,那说明服务器出错。
                else {
                    iSquareView.showServerErrorMsg();
                }
            }

            @Override
            public void onFail(String error) {
                //网络不好,提示相应的提示
                iSquareView.showErrorMsg();
            }
        });

    }

    @Override
    public void getContentData( ) {
        squareModel.getContentData(new OnHttpCallBack<SubjectPiazzaModel>() {
            @Override
            public void onSuccess(SubjectPiazzaModel data) {
                //如果返回的状态码为成功再解析数据
                if(data.errCode.equals(Constant.SUCCESS_CODE)){
                    List<SubjectPiazzaModel.ColumnOverview> columnOverviews=data.result.columnOverviews;
                    //刷新列表数据
                    iSquareView.refreshContentData(columnOverviews);
                }else{
                    //如果返回不是成功的状态码,那说明服务器出错。
                    iSquareView.showServerErrorMsg();
                }
                //刷新成功后关闭下拉刷新进度条
                iSquareView.hideProgress();
            }

            @Override
            public void onFail(String error) {
                //刷新失败后关闭下拉刷新进度条,并且显示网络错误提示
                iSquareView.hideProgress();
                iSquareView.showErrorMsg();
            }
        });


    }
}
/**
 * 此model只负责数据的获取并且转换成对应的数据结构进行保存
 */
public class SquareModel implements SquareContract.ISquareModel{
    @Override
    public void getHeaderData(final OnHttpCallBack<AdvertisementsBean> callBacK) {
        //Constant.queryAdvertisements(Constant.LOGIN_TOKEN)获得访问地址
        VolleyUtil.getInstance().get(Constant.queryAdvertisements(Constant.LOGIN_TOKEN),
                new VolleyUtil.JsonCallbackListener() {
            @Override
            public void onSucceed(String jsonString) {
                //此数据结构对应的bean
                AdvertisementsBean data= GsonUtil.getInstance().fromJson(jsonString,AdvertisementsBean.class);
                //回调返回数据结构
                callBacK.onSuccess(data);
            }

            @Override
            public void onFail(String errorMessage) {
                callBacK.onFail(errorMessage);
            }
        });
    }

    @Override
    public void getContentData(final OnHttpCallBack<SubjectPiazzaBean> callBacK) {
        //Constant.subjectPiazza(Constant.LOGIN_TOKEN)获得访问地址
        VolleyUtil.getInstance().get(Constant.subjectPiazza(Constant.LOGIN_TOKEN),
                new VolleyUtil.JsonCallbackListener() {
            @Override
            public void onSucceed(String jsonString) {
                SubjectPiazzaBean data=GsonUtil.getInstance().fromJson(jsonString,SubjectPiazzaBean.class);
                callBacK.onSuccess(data);
            }

            @Override
            public void onFail(String errorMessage) {
                callBacK.onFail(errorMessage);
            }
        });
    }
}

附上两个javabean的数据结构

public class AdvertisementsBean extends BaseBean {


    public Result result;


    public class Result{
        public List<Advertisement> advertisements;
    }
    public class Advertisement{

        public String coverHeight;
        public String coverType;
        public String coverUrl;
        public String coverWidth;
        public String description;
        public String id;
        public String jumpUrl;
    }

}
public class SubjectPiazzaBean extends BaseBean {
    public Result result;

    public class Result{
        public List<ColumnOverview> columnOverviews;
    }

    public class ColumnOverview{
        public ColumnBrief columnBrief;
        public List<imgView> imgViews;
    }

    public class ColumnBrief{
        public String descrption;
        public String id;
        public String name;
    }

    public class imgView{
        public String imgMediaId;
        public String imgUrl;
        public String subjectId;
        public String subjectTitle;
    }

}

看到这里代码的结构是不是异常的清晰?Activity也没有那么臃肿了?

版权声明:本文为博主原创文章,未经博主允许不得转载。

MVP+Databinding模式开发APP(一)

前言:本文适合了解入门MVP和Databinding的小伙伴们。小伙伴可能有疑问,为什么要用MVP+Databinding,因为我觉得MVP的三层非常的完美,Persenter层彻底的把Model层和...

仅需6步,教你轻易撕掉app开发框架的神秘面纱(3):构造具有个人特色的MVP模式

之前我们说过MVP模式最大的问题在于:每写一个Activity/Fragment需要写4个对应的文件,对于一个简易的app框架来说太麻烦了。所以我们需要对MVP进行一定的简化。 关于MVP模式介绍,...

Mvp+DataBinding DEMO

  • 2016年12月12日 16:24
  • 21.67MB
  • 下载

DataBinding 与 mvvm 模式(二)其他类型数据绑定

本文介绍绑定颜色数据、绑定本地图片资源以及绑定网络图片三个案例,对于除了文本类型数据之外的其他类型数据,我们可以通过改造 getXxx 和 @BindingAdapter 注解两种方法实现绑定,推荐使...
  • yhaolpz
  • yhaolpz
  • 2017年03月29日 21:01
  • 1357

玩转Android之MVVM开发模式实战,炫酷的DataBinding!

C# 很早就有了MVVM的开发模式,Android手机中的MVVM一直到去年Google的I\O大会上才推出,姗姗来迟。MVVM这中开发模式的优点自不必多说,可以实现视图和逻辑代码的解耦,而且,按照G...

Android App的三种架构模式MVC,MVP和MVVM

Android App的三种架构模式MVC,MVP和MVVM

玩转Android之MVVM开发模式实战,炫酷的DataBinding!

C# 很早就有了MVVM的开发模式,Android手机中的MVVM一直到去年Google的I\O大会上才推出,姗姗来迟。MVVM这中开发模式的优点自不必多说,可以实现视图和逻辑代码的解耦,而且,按照G...

Android开发模式MVVM之DataBinding

转载:http://blog.csdn.net/jdsjlzx/article/details/48133293 今天来了解一下Android最新给我们带来的数据绑定框架——Data Bin...

Android MVVM架构模式(二)——DataBinding框架(二)

Android MVVM架构模式(二)——DataBinding框架(二)一 表达式 支持的表达式: 数学计算 + - / * %字符串连接 +逻辑 && ||二进制 & | ^一元运算符 + -...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:MVP+Databinding模式开发APP(二)
举报原因:
原因补充:

(最多只允许输入30个字)