Android 设计模式之MVP,从实例中体现MVP

前言

今天早上写过一篇文章,Android的模式MVC,但是在文章的末尾我也说到了还有一种MVP,于是这一篇就来写一写MVC的衍生版本MVP。

名言
士搏出惊涛骇流而不沉沦,懦夫在风平浪静也会溺水。


为啥每次你都喜欢说一句名言呢?因为我励志吗?因为我勤奋吗?因为好看吗?
装逼!装逼!只是为了装逼!其实也不是装逼那,也算是随时的警示自己吧mHahahahaha…
这里写图片描述


什么是mvp?

MVC的演化版本,让Model和View完全解耦,上一篇中我们也说到了其实MVC没有真的的解耦,但是MVP做到了。
MVP—->Model+View+Presenter
M : 还是业务层和模型层
V : 视图层的责任由Activity来担当
P : 新成员Prensenter 用来代理 C(control) 控制层


接下来我们从一个实例中来看看MVP

这里写图片描述


还是先来看看项目的整体结构
这里写图片描述

解释一下
News—>请求数据的实体类
MyService—> Retrofit请求网络的接口
NewsModel—>M和P的交互接口
NewsModelImpl—>请求接口逻辑处理
NewsP—>P和V的逻辑交互接口
NewsPImpl—>连接M和V的逻辑
OnNewsSuccessListener—>请求成功的接口
MainActivity—>作为V层使用
NewsView—>P和V页面交互接口

第一步xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <EditText
        android:id="@+id/edit"
        android:layout_width="match_parent"
        android:layout_height="44dp"
        android:layout_margin="16dp"
        android:gravity="center"
        android:hint="请输入类别"
        android:textColorHint="@color/colorAccent"
        android:textSize="16sp" />


    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="44dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:gravity="center"
        android:text="查找"
        android:textSize="16dp" />

    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="44dp"
        android:layout_margin="16dp"
        android:gravity="center"
        android:textColor="@color/colorPrimaryDark"
        android:textSize="16sp" />


    <ImageView
        android:id="@+id/img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp" />


</LinearLayout>

M层代码

请求网络的接口

public interface MyService {
    @FormUrlEncoded
    @POST("/toutiao/index")
    Call<News> getNews(@Field("key") String key,
                       @Field("type") String type);
}

M和P的交互接口

public interface NewsModel {
    void getNews(String type, OnNewsSussesListener mlistener);
}

请求成功的接口

public interface OnNewsSussesListener {
    void onSuccess(News news);
    void onErrorRequest();
}

M的网络请求逻辑代码

public class NewsModelImpl implements NewsModel {
    private final String baseUrl = "http://v.juhe.cn";
    private final String key = "这里是自己在聚合数据申请的key";
    @Override
    public void getNews(String type, final OnNewsSussesListener mlistener) {
        //进行网络请求
        OkHttpClient.Builder client = new OkHttpClient.Builder();
        Retrofit retrofit = new Retrofit.Builder()
                .client(client.build())
                .baseUrl(baseUrl)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        MyService service = retrofit.create(MyService.class);
        service.getNews(key,type).enqueue(new Callback<News>() {
            @Override
            public void onResponse(Call<News> call, Response<News> response) {
                News news = response.body();
                if (news.getReason().equals("成功的返回")) {
                    Log.e("news", "成功");
                   mlistener.onSuccess(news);
                } else {
                    mlistener.onErrorRequest();
                    Log.e("news", "失败");
                }
            }
            @Override
            public void onFailure(Call<News> call, Throwable t) {
                t.getStackTrace();
                mlistener.onErrorRequest();
            }
        });
    }
}

P层代码

P和V的数据交互接口

public interface NewsP {
    void getNews(String type);
}

P层吧V和M联系起来的代码

public class NewsPImpl implements NewsP, OnNewsSussesListener {
    private NewsView newsView = null;
    private NewsModel newsmodel = null;

    public NewsPImpl(NewsView newsView) {
        this.newsView = newsView;
        this.newsmodel = new NewsModelImpl();
    }

    @Override
    public void getNews(String type) {
        if (type.equals("")) {
            newsView.onError();
        } else {
            newsmodel.getNews(type, this);
        }
    }

    @Override
    public void onSuccess(News news) {
        if (newsView != null) {
            newsView.setview(news);
        }
    }

    @Override
    public void onErrorRequest() {
        if (newsView != null) {
            newsView.onError();
        }
    }
}

V层代码

V和P界面交互接口

public interface NewsView {
    void setview(News news);
    void onError();
}

MainActivity代码

public class MainActivity extends AppCompatActivity implements NewsView, View.OnClickListener {

    private EditText editText = null;
    private Button button = null;
    private ImageView img = null;
    private TextView title = null;

    private NewsP np = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    public void initView() {
        editText = (EditText) findViewById(R.id.edit);
        button = (Button) findViewById(R.id.button);
        img = (ImageView) findViewById(R.id.img);
        title = (TextView) findViewById(R.id.title);
        button.setOnClickListener(this);
        np = new NewsPImpl(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button:
                np.getNews(editText.getText().toString());
                break;
        }
    }

    @Override
    public void setview(News news) {
        //设置数据
        title.setText(news.getResult().getData().get(1).getTitle());
        //图片这个地方用的是Glide框架
        Glide.with(this).load(news.getResult().getData().get(1).getThumbnail_pic_s()).into(img);
    }

    @Override
    public void onError() {
        Toast.makeText(this, "出错了,小哥", Toast.LENGTH_SHORT).show();
    }
}

一切尽在代码中
然后我总结了一个大致的流程
这里写图片描述

谢谢~~~~有不对的地方还望指出。

基本功能 2016/10/31 添加抽奖功能,修复已知Bug(点击删除购物,出现闪退bug) 2016/10/28 添加微信分享功能 2016/10/28 添加忘记密码功能、完善用户评价系统、以及完善订单页面按钮功能及显示 2016/10/27 添加自动更新功能,修复已知的登陆闪退Bug 2016/10/26 添加订单查询(全部订单、待付款、待发货、待收货、待评价、退款和售后等查询)以及显示功能,收藏宝贝查询、及显示功能 2016/10/25 添加加入购物车功能、移除购物车的商品和下单之后更新购物车等功能 2016/10/24 添加评论功能的显示、登陆用户的收藏和取消收藏功能、下单页面的显示、以及下单功能的实现 2016/10/23 添加商品的类别显示、分类查询展示、固定数据的搜索(暂时数据固定) 2016/10/22 添加用户注销功能、头像的上传以及更新用户个人资料功能 2016/10/20 添加注册、登陆、加载默认头像等功能、解决ViewPager Fragment Fragment被预加载问 2016/10/19 进行主页、微淘、问大家、购物车、我的淘宝等页面的设计、添加轮播图、资讯滚动条功能 2016/10/18 构建基本MVP框架 开发过程遇到的问题(可能导致程序无法运行的bug)及解决方案 当用户未登录时,点击购物车,登陆之后,程序闪退 出现问题 :NullPointerException 解决方案: 使用Fragment的延时加载(懒加载)实现对数据的加载 拍照时无法进行图片的裁剪(不断加载) 解决步骤如下: Activity跳转时图库时的Intent如下 Intent takePhotoIntent = new Intent( “android.media.action.IMAGE_CAPTURE”); takePhotoIntent.putExtra( MediaStore.EXTRA_OUTPUT, imageUri); 在onActivityResult()方法调用P层进行处理,相关代码如下 String uri = Environment.getExternalStorageDirectory() “/icoImage.jpg”; if(!allSelectedPicture.contains(uri)){ allSelectedPicture.add(uri); } ViewPager和Fragment结合使用,Fragment出现被预计载的情况 解决方案 项目使用的主要技术及框架 框架 ButterKnife 注解绑定获取控件功能 Picasso 网络和本地图片的加载功能 okhttp 网络连接功能
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值