retrofit+rxjava+okhttp3+mvp+fresco+butterknift+eventbus+recyclerview的综合练习

//实现一个商品展示,跳转传值的功能

先进行项目开始前的配置工作:

//权限:

<uses-permission android:name="android.permission.INTERNET" />

//fresco的配置,

请看https://blog.csdn.net/qq_43668258/article/details/85556883

 

//butterknife的配置和使用:

基本配置
在android Studio项目中配置使用ButterKnife

  • Step one:在Project的 build.gradle 中添加如下代码:
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.3'
        classpath 'com.jakewharton:butterknife-gradle-plugin:8.8.1'  //添加这一行
    }
}
  • Step two:在App的 build.gradle 中添加如下代码:
apply plugin: 'com.jakewharton.butterknife'
  • dependencies中添加:
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'

eventBus的依赖

implementation 'org.greenrobot:eventbus:3.1.1'

recyclerview的依赖

implementation 'com.android.support:recyclerview-v7:28.0.0'

gson的依赖

 implementation 'com.google.code.gson:gson:2.8.5'

okhttp3的依赖

implementation 'com.squareup.okhttp3:okhttp:3.12.1'
implementation "com.squareup.okhttp3:logging-interceptor:$rootProject.interceptor"

retrofit+rxjava的配置

这个是在项目的build.grade里面直接粘过去就OK
ext {
    // Sdk and tools
    minSdkVersion = 19
    targetSdkVersion = 26
    compileSdkVersion = 26
    buildToolsVersion = '26.0.2'
    //support版本
    supportVersion = '27.1.0'
    constraintLayout = '1.0.2'
    junit = '4.12'
    testRunner = '1.0.1'
    espressoCore = '3.0.1'

    interceptor = "3.11.0"
    retrofit = '2.3.0'
    converterGson = '2.3.0'
    rxandroid = '1.2.1'
    rxjava = '1.3.0'
    rxbus = '1.0.6'
    adapterRxjava = '2.0.2'
}

依赖

    implementation "com.squareup.retrofit2:retrofit:$rootProject.retrofit"
    implementation "com.squareup.retrofit2:converter-gson:$rootProject.converterGson"
    implementation "io.reactivex:rxandroid:$rootProject.rxandroid"
    implementation "io.reactivex:rxjava:$rootProject.rxjava"
    implementation "com.hwangjr.rxbus:rxbus:$rootProject.rxbus"
    implementation "com.squareup.retrofit2:adapter-rxjava:$rootProject.adapterRxjava"

以上就是基本的环境配置,下面开始主要的代码和实现方式

首先说一下思路:

整体模式采用MVP的模式实现  

网络获取数据采用:retrofit+rxjava+okhttp结合mvp实现

数据的展示采用recyclerview实现,实现布局的切换方式,

图片加载,使用Rresco实现

主页与详情页的网址传递采用EventBus实现

 

首先,开始创建Bean类,MVP模式,和网络请求的工具类

Bean类

public class GoodBean {

    /**
     * msg : 查询成功
     * code : 0
     * data : [{"bargainPrice":99,"createtime":"2017-10-14T21:38:26","detailUrl":"https://item.m.jd.com/product/4345173.html?utm#_source=androidapp&utm#_medium=appshare&utm#_campaign=t#_335139774&utm#_term=QQfriends","images":"https://m.360buyimg.com/n0/jfs/t6037/35/2944615848/95178/6cd6cff0/594a3a10Na4ec7f39.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t6607/258/1025744923/75738/da120a2d/594a3a12Ne3e6bc56.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t6370/292/1057025420/64655/f87644e3/594a3a12N5b900606.jpg!q70.jpg","itemtype":1,"pid":45,"price":2999,"pscid":39,"salenum":4666,"sellerid":1,"subhead":"高清双摄,就是清晰!2000+1600万高清摄像头,6GB大内存+高通骁龙835处理器,性能怪兽!","title":"一加手机5 (A5000) 6GB+64GB 月岩灰 全网通 双卡双待 移动联通电信4G手机"},{"bargainPrice":6666,"createtime":"2017-10-10T16:01:31","detailUrl":"https://item.m.jd.com/product/5089273.html?utm#_source=androidapp&utm#_medium=appshare&utm#_campaign=t#_335139774&utm#_term=QQfriends","images":"https://m.360buyimg.com/n0/jfs/t8284/363/1326459580/71585/6d3e8013/59b857f2N6ca75622.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t9346/182/1406837243/282106/68af5b54/59b8480aNe8af7f5c.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t8434/54/1359766007/56140/579509d9/59b85801Nfea207db.jpg!q70.jpg","itemtype":0,"pid":46,"price":234,"pscid":39,"salenum":868,"sellerid":2,"subhead":"【iPhone新品上市】新一代iPhone,让智能看起来更不一样","title":"Apple iPhone 8 Plus (A1864) 64GB 金色 移动联通电信4G手机"},{"bargainPrice":1599,"createtime":"2017-10-14T21:48:08","detailUrl":"https://item.m.jd.com/product/1993026402.html?utm#_source=androidapp&utm#_medium=appshare&utm#_campaign=t#_335139774&utm#_term=QQfriends","images":"https://m.360buyimg.com/n0/jfs/t5863/302/8961270302/97126/41feade1/5981c81cNc1b1fbef.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t7003/250/1488538438/195825/53bf31ba/5981c57eN51e95176.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t5665/100/8954482513/43454/418611a9/5981c57eNd5fc97ba.jpg!q70.jpg","itemtype":2,"pid":47,"price":111,"pscid":39,"salenum":757,"sellerid":3,"subhead":"碳黑色 32GB 全网通 官方标配   1件","title":"锤子 坚果Pro 特别版 巧克力色 酒红色 全网通 移动联通电信4G手机 双卡双待 碳黑色 32GB 全网通"},{"bargainPrice":3455,"createtime":"2017-10-14T21:38:26","detailUrl":"https://item.m.jd.com/product/12224420750.html?utm_source=androidapp&utm_medium=appshare&utm_campaign=t_335139774&utm_term=QQfriends","images":"https://m.360buyimg.com/n0/jfs/t9106/106/1785172479/537280/253bc0ab/59bf78a7N057e5ff7.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t9106/106/1785172479/537280/253bc0ab/59bf78a7N057e5ff7.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t8461/5/1492479653/68388/7255e013/59ba5e84N91091843.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t8461/5/1492479653/68388/7255e013/59ba5e84N91091843.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t8803/356/1478945529/489755/2a163ace/59ba5e84N7bb9a666.jpg!q70.jpg","itemtype":1,"pid":48,"price":222,"pscid":39,"salenum":656,"sellerid":4,"subhead":"【现货新品抢购】全面屏2.0震撼来袭,骁龙835处理器,四曲面陶瓷机","title":"小米(MI) 小米MIX2 手机 黑色 全网通 (6GB+64GB)【标配版】"},{"bargainPrice":1999,"createtime":"2017-10-10T16:09:02","detailUrl":"https://item.m.jd.com/product/5025971.html?utm#_source=androidapp&utm#_medium=appshare&utm#_campaign=t#_335139774&utm#_term=QQfriends","images":"https://m.360buyimg.com/n0/jfs/t7210/232/3738666823/232298/9004583e/59c3a9a7N8de42e15.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t8356/82/2107423621/109733/c019b8c6/59c3a9a6Ne9a4bdd7.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t10219/74/25356012/171379/7d55e296/59c3a9a8N82fa6e02.jpg!q70.jpg","itemtype":0,"pid":49,"price":333,"pscid":39,"salenum":123,"sellerid":5,"subhead":"vivo X20 带你开启全面屏时代!逆光也清晰,照亮你的美!","title":"vivo X20 全面屏手机 全网通 4GB+64GB 金色 移动联通电信4G手机 双卡双待"},{"bargainPrice":3455,"createtime":"2017-10-14T21:48:08","detailUrl":"https://item.m.jd.com/product/12224420750.html?utm_source=androidapp&utm_medium=appshare&utm_campaign=t_335139774&utm_term=QQfriends","images":"https://m.360buyimg.com/n0/jfs/t9106/106/1785172479/537280/253bc0ab/59bf78a7N057e5ff7.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t9106/106/1785172479/537280/253bc0ab/59bf78a7N057e5ff7.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t8461/5/1492479653/68388/7255e013/59ba5e84N91091843.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t8461/5/1492479653/68388/7255e013/59ba5e84N91091843.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t8803/356/1478945529/489755/2a163ace/59ba5e84N7bb9a666.jpg!q70.jpg","itemtype":2,"pid":50,"price":444,"pscid":39,"salenum":54,"sellerid":6,"subhead":"【现货新品抢购】全面屏2.0震撼来袭,骁龙835处理器,四曲面陶瓷机","title":"小米(MI) 小米MIX2 手机 黑色 全网通 (6GB+64GB)【标配版】"},{"bargainPrice":3455,"createtime":"2017-10-14T21:38:26","detailUrl":"https://item.m.jd.com/product/12224420750.html?utm_source=androidapp&utm_medium=appshare&utm_campaign=t_335139774&utm_term=QQfriends","images":"https://m.360buyimg.com/n0/jfs/t9106/106/1785172479/537280/253bc0ab/59bf78a7N057e5ff7.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t9106/106/1785172479/537280/253bc0ab/59bf78a7N057e5ff7.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t8461/5/1492479653/68388/7255e013/59ba5e84N91091843.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t8461/5/1492479653/68388/7255e013/59ba5e84N91091843.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t8803/356/1478945529/489755/2a163ace/59ba5e84N7bb9a666.jpg!q70.jpg","itemtype":1,"pid":51,"price":555,"pscid":39,"salenum":424,"sellerid":7,"subhead":"【现货新品抢购】全面屏2.0震撼来袭,骁龙835处理器,四曲面陶瓷机","title":"小米(MI) 小米MIX2 手机 黑色 全网通 (6GB+64GB)【标配版】"},{"bargainPrice":3455,"createtime":"2017-10-03T23:53:28","detailUrl":"https://item.m.jd.com/product/12224420750.html?utm_source=androidapp&utm_medium=appshare&utm_campaign=t_335139774&utm_term=QQfriends","images":"https://m.360buyimg.com/n0/jfs/t9106/106/1785172479/537280/253bc0ab/59bf78a7N057e5ff7.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t9106/106/1785172479/537280/253bc0ab/59bf78a7N057e5ff7.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t8461/5/1492479653/68388/7255e013/59ba5e84N91091843.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t8461/5/1492479653/68388/7255e013/59ba5e84N91091843.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t8803/356/1478945529/489755/2a163ace/59ba5e84N7bb9a666.jpg!q70.jpg","itemtype":0,"pid":52,"price":666,"pscid":39,"salenum":212,"sellerid":8,"subhead":"【现货新品抢购】全面屏2.0震撼来袭,骁龙835处理器,四曲面陶瓷机","title":"小米(MI) 小米MIX2 手机 黑色 全网通 (6GB+64GB)【标配版】"},{"bargainPrice":2999,"createtime":"2017-10-14T21:48:08","detailUrl":"https://item.m.jd.com/product/2385655.html?utm#_source=androidapp&utm#_medium=appshare&utm#_campaign=t#_335139774&utm#_term=QQfriends","images":"https://m.360buyimg.com/n0/jfs/t2068/298/2448145915/157953/7be197df/56d51a42Nd86f1c8e.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t2437/128/1687178395/117431/bcc190c1/56d3fcbaNb2963d21.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t2467/222/2263160610/95597/927b8a2f/56d3eafeNdecebeb6.jpg!q70.jpg","itemtype":2,"pid":53,"price":777,"pscid":39,"salenum":0,"sellerid":9,"subhead":"Super AMOLED三星双曲面2K 屏,支持无线充电!","title":"三星 Galaxy S7 edge(G9350)4GB+32GB 铂光金 移动联通电信4G手机 双卡双待"},{"bargainPrice":3455,"createtime":"2017-10-03T23:53:28","detailUrl":"https://item.m.jd.com/product/12224420750.html?utm_source=androidapp&utm_medium=appshare&utm_campaign=t_335139774&utm_term=QQfriends","images":"https://m.360buyimg.com/n0/jfs/t9106/106/1785172479/537280/253bc0ab/59bf78a7N057e5ff7.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t9106/106/1785172479/537280/253bc0ab/59bf78a7N057e5ff7.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t8461/5/1492479653/68388/7255e013/59ba5e84N91091843.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t8461/5/1492479653/68388/7255e013/59ba5e84N91091843.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t8803/356/1478945529/489755/2a163ace/59ba5e84N7bb9a666.jpg!q70.jpg","itemtype":0,"pid":54,"price":888,"pscid":39,"salenum":7575,"sellerid":10,"subhead":"【现货新品抢购】全面屏2.0震撼来袭,骁龙835处理器,四曲面陶瓷机","title":"小米(MI) 小米MIX2 手机 黑色 全网通 (6GB+64GB)【标配版】"}]
     * page : 1
     */

    private String msg;
    private String code;
    private String page;
    private List<DataBean> data;

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getPage() {
        return page;
    }

    public void setPage(String page) {
        this.page = page;
    }

    public List<DataBean> getData() {
        return data;
    }

    public void setData(List<DataBean> data) {
        this.data = data;
    }

    public static class DataBean {
        /**
         * bargainPrice : 99.0
         * createtime : 2017-10-14T21:38:26
         * detailUrl : https://item.m.jd.com/product/4345173.html?utm#_source=androidapp&utm#_medium=appshare&utm#_campaign=t#_335139774&utm#_term=QQfriends
         * images : https://m.360buyimg.com/n0/jfs/t6037/35/2944615848/95178/6cd6cff0/594a3a10Na4ec7f39.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t6607/258/1025744923/75738/da120a2d/594a3a12Ne3e6bc56.jpg!q70.jpg|https://m.360buyimg.com/n0/jfs/t6370/292/1057025420/64655/f87644e3/594a3a12N5b900606.jpg!q70.jpg
         * itemtype : 1
         * pid : 45
         * price : 2999.0
         * pscid : 39
         * salenum : 4666
         * sellerid : 1
         * subhead : 高清双摄,就是清晰!2000+1600万高清摄像头,6GB大内存+高通骁龙835处理器,性能怪兽!
         * title : 一加手机5 (A5000) 6GB+64GB 月岩灰 全网通 双卡双待 移动联通电信4G手机
         */

        private double bargainPrice;
        private String createtime;
        private String detailUrl;
        private String images;
        private int itemtype;
        private int pid;
        private double price;
        private int pscid;
        private int salenum;
        private int sellerid;
        private String subhead;
        private String title;

        public double getBargainPrice() {
            return bargainPrice;
        }

        public void setBargainPrice(double bargainPrice) {
            this.bargainPrice = bargainPrice;
        }

        public String getCreatetime() {
            return createtime;
        }

        public void setCreatetime(String createtime) {
            this.createtime = createtime;
        }

        public String getDetailUrl() {
            return detailUrl;
        }

        public void setDetailUrl(String detailUrl) {
            this.detailUrl = detailUrl;
        }

        public String getImages() {
            return images;
        }

        public void setImages(String images) {
            this.images = images;
        }

        public int getItemtype() {
            return itemtype;
        }

        public void setItemtype(int itemtype) {
            this.itemtype = itemtype;
        }

        public int getPid() {
            return pid;
        }

        public void setPid(int pid) {
            this.pid = pid;
        }

        public double getPrice() {
            return price;
        }

        public void setPrice(double price) {
            this.price = price;
        }

        public int getPscid() {
            return pscid;
        }

        public void setPscid(int pscid) {
            this.pscid = pscid;
        }

        public int getSalenum() {
            return salenum;
        }

        public void setSalenum(int salenum) {
            this.salenum = salenum;
        }

        public int getSellerid() {
            return sellerid;
        }

        public void setSellerid(int sellerid) {
            this.sellerid = sellerid;
        }

        public String getSubhead() {
            return subhead;
        }

        public void setSubhead(String subhead) {
            this.subhead = subhead;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }
    }
}

//网络工具类

//        用来处理接口的API接口   封装了一个get和post方式  观察者模式

public interface MyServiceApi {
    //封装Get和post方式    被观察者    Observable注意导包Rx的包
    @GET
    Observable<ResponseBody> get(@Url String url, @QueryMap Map<String, Integer> map);
    //http://www.zhaoapi.cn/product/searchProducts?keywords=手机&page=1&sort=0
    @POST
    Observable<ResponseBody>post(@Url String url,@QueryMap Map<String, Integer> map);
}

//      用来管理网址的类

public class Contacts {
    //http://www.zhaoapi.cn/product/searchProducts?keywords=手机&page=1&sort=0
    //用来存放所有的接口
    //总接口前缀
    public static final String BASE_URL="http://www.zhaoapi.cn/";
    //商品详情
    public static final String USER_SHOP="product/searchProducts?keywords=手机";
}

//    retrofit工具类

public class RetrofitUnits {
    private final MyServiceApi myServiceApi;

    //fitst:创建管理接口的Api接口和管理网址的类
    //单例模式

    public RetrofitUnits() {
        //日志拦截器
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
        /*setlevel用来设置日志打印的级别,共包括了四个级别:NONE,BASIC,HEADER,BODY
          BASEIC:请求/响应行
          HEADER:请求/响应行 + 头
          BODY:请求/响应行+ 头 + 体
        * */
        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        //初始化OkHttp3
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                //OkHttp3中设置超时的方法
                .readTimeout(20,TimeUnit.SECONDS)
                .writeTimeout(20,TimeUnit.SECONDS)
                .connectTimeout(20,TimeUnit.SECONDS)
                //添加拦截器
                .addInterceptor(loggingInterceptor)
                //配置此客户端,以便在遇到连接问题时重试或不重试。默认情况下,
                //*该客户端从以下问题中悄悄恢复
                .retryOnConnectionFailure(true)
                .build();
        //初始化Retrofit  结合Gson等操作
        Retrofit retrofit = new Retrofit.Builder()
                //结合Gson解析   添加相应结果解析器,存放于Retrofit.Builder类的converterFactories集合中。
                .addConverterFactory(GsonConverterFactory.create())
                //添加访问处理适配器,存放于Retrofit.Builder类的adapterFactories集合中。
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                //解析我们传入的url参数生成一个HttpUrl对象存放于Retrofit. Builder类的成员变量baseUrl中。
                .baseUrl(Contacts.BASE_URL)
                //添加网络访问工具OKHttpClient,保存在Retrofit.Builder类的callFactory变量中.
                .client(okHttpClient)
                .build();
        //通过Retrofit创建  Api 调用方法
        myServiceApi = retrofit.create(MyServiceApi.class);
    }

    public static RetrofitUnits getInstance(){
        return RetrofitHolder.retro;
    }

    static class RetrofitHolder{
        private static final RetrofitUnits retro=new RetrofitUnits();
    }


    //封装的Gson  和  Get  方法
    //封装Get方式  这里面采用构造者模式  就是调用这个方法有返回自己本身这个对象
    public RetrofitUnits get(String url, Map<String,Integer>map){
        //订阅者事件(处理网络请求)
        //Schedulers 线程调度器  指定Observable自身在哪个调度器上执行  io子线程

        /*
         subscribeOn(): 指定Observable(被观察者)所在的线程,或者叫做事件产生的线程。
         observeOn(): 指定 Observer(观察者)所运行在的线程,或者叫做事件消费的线程。*/
        myServiceApi.get(url,map)
                .subscribeOn(Schedulers.io())
                //指定一个观察者在哪个调度器上观察这个Observable  主线程
                .observeOn(AndroidSchedulers.mainThread())
                //订阅者
                .subscribe(observer);
        return RetrofitUnits.getInstance();
    }
    //post方法
    public RetrofitUnits post(String url, Map<String, Integer> map){
        if (map==null){
            map=new HashMap<>();
        }
        myServiceApi.post(url,map)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
        return RetrofitUnits.getInstance();
    }
    //重写一个观察者
    private Observer observer=new Observer<ResponseBody>(){
        @Override
        public void onCompleted() {

        }
        //网络处理失败
        @Override
        public void onError(Throwable e) {
            //判断网络状态
            if (httpListener!=null){
                httpListener.onError(e.getMessage());
            }
        }
        //网络处理成功
        @Override
        public void onNext(ResponseBody responseBody) {
            if (httpListener!=null){
                try {
                    httpListener.onSuccess(responseBody.string());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    };

    //接口回调,网络请求数据成功与失败
    public interface HttpListener{
        //成功
        void onSuccess(String jsonStr);
        //失败
        void onError(String error);
    }

    public HttpListener httpListener;

    public void setHttpListener(HttpListener listener){
        this.httpListener=listener;
    }
}

//MVP模式:

契约类   用于管理MVP中的接口

public interface MyInterface {
    interface Callbacks<T>{
        void setData(T data);
        void setError(T error);
    }

    interface View<T>{
        void success(T data);
        void error(T error);
    }

    interface IModel{
        void getData(String url, Map<String,Integer> params, Class clazz, Callbacks callbacks);
    }

    interface IPresenter{
        void startRequestData(String url, Map<String,Integer> params, Class clazz);
    }

}

M

public class IModelImpl implements IModel {
    private MyInterface.Callbacks callbacks;

    @Override
    public void getData(String url, Map<String, Integer> params, final Class clazz, final MyInterface.Callbacks callbacks) {
        this.callbacks=callbacks;
        //构造者模式    post请求
        RetrofitUnits.getInstance().post(url,params).setHttpListener(new RetrofitUnits.HttpListener() {
            @Override
            public void onSuccess(String jsonStr) {
                Gson gson = new Gson();
                Object o = gson.fromJson(jsonStr, clazz);
                callbacks.setData(o);
            }

            @Override
            public void onError(String error) {
                callbacks.setError(error);
            }
        });
    }

}

P

public class IPresenterImpl implements MyInterface.IPresenter {
    private MyInterface.View view;
    private IModelImpl iModel;

    public IPresenterImpl(MyInterface.View view) {
        this.view = view;
        iModel = new IModelImpl();
    }

    @Override
    public void startRequestData(String url, Map<String, Integer> params, Class clazz) {
        iModel.getData(url, params, clazz, new MyInterface.Callbacks() {
            @Override
            public void setData(Object data) {
                view.success(data);
            }

            @Override
            public void setError(Object error) {
                view.error(error);
            }
        });
    }

    //处理内存泄漏
    public void onDetch() {
        if (view != null) {
            view = null;
        }
        if (iModel != null) {
            iModel = null;
        }
    }
}

V  ACTIVITY

public class MainActivity<T> extends AppCompatActivity implements MyInterface.View<T> {

    @BindView(R.id.searchView)
    SearchView searchView;
    @BindView(R.id.btn_menu)
    ImageView btnMenu;
    @BindView(R.id.btn_zonghe)
    Button btnZonghe;
    @BindView(R.id.btn_xiaoliang)
    Button btnXiaoliang;
    @BindView(R.id.btn_jiage)
    Button btnJiage;
    @BindView(R.id.shaixuan)
    Button shaixuan;
    @BindView(R.id.Recycler_view)
    android.support.v7.widget.RecyclerView RecyclerView;
    private IPresenterImpl iPresenter;
    private boolean isShow=true;
    private int page=1;
    private int sort=0;
    private ArrayList<GoodBean.DataBean>mGood=new ArrayList<>();
    private MyRecyclerViewAdapter myRecyclerViewAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        //注册EventBus
        EventBus.getDefault().register(this);

        //实例化P层对象,调用方法
        iPresenter = new IPresenterImpl(this);
        //设置适配器,布局管理器
        setLayoutManger();
        //开始请求数据
        startRequestDatas(page,sort);

        myRecyclerViewAdapter.setGoodsClick(new MyRecyclerViewAdapter.goodsClick() {
            @Override
            public void onGoodsClick(int position) {
                startActivity(new Intent(MainActivity.this,WebActivity.class));
                String url = mGood.get(position).getDetailUrl();
                int pid = mGood.get(position).getPid();
                String replace = url.replace("https", "http");
                String urls=replace+pid;
                EventBus.getDefault().postSticky(urls);
            }
        });
    }
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void getInfo(Object object){

    }

    private void startRequestDatas(int page,int sort) {
        Map<String,Integer>map=new HashMap<>();
            map.put("page",page);
            map.put("sort",sort);
        iPresenter.startRequestData(Contacts.USER_SHOP,map,GoodBean.class);
        myRecyclerViewAdapter.notifyDataSetChanged();
    }

    @OnClick({R.id.btn_menu, R.id.btn_zonghe, R.id.btn_xiaoliang, R.id.btn_jiage, R.id.shaixuan})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.btn_menu:
                    setLayoutManger();
                break;
            case R.id.btn_zonghe:
                mGood.clear();
                startRequestDatas(page,sort);
                break;
            case R.id.btn_xiaoliang:
                mGood.clear();
                int sortx=1;
                startRequestDatas(page,sortx);
                break;
            case R.id.btn_jiage:
                mGood.clear();
                int sorty=2;
                startRequestDatas(page,sorty);
                break;
            case R.id.shaixuan:
                break;
        }
    }
    private void setLayoutManger() {
        if (isShow==true){
            //线性布局管理器
            RecyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayout.VERTICAL,false));
            RecyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL));
            myRecyclerViewAdapter = new MyRecyclerViewAdapter(this, mGood, isShow);
            isShow=false;
        }else if(isShow==false){
            //网格布局管理器
            RecyclerView.setLayoutManager(new GridLayoutManager(this,2));
            //分割线
            RecyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.HORIZONTAL));
            myRecyclerViewAdapter = new MyRecyclerViewAdapter(this, mGood, isShow);
            isShow=true;
        }
        RecyclerView.setAdapter(myRecyclerViewAdapter);
    }

    //成功时调用的方法
    @Override
    public void success(T data) {
        if (data instanceof GoodBean) {
            /*Toast.makeText(this, ((GoodBean) data).getMsg(), Toast.LENGTH_SHORT).show();*/
            GoodBean goodBean= (GoodBean) data;
            mGood.addAll(goodBean.getData());
            //刷新适配器
            myRecyclerViewAdapter.notifyDataSetChanged();
        }
    }

    //失败后调用的方法
    @Override
    public void error(T error) {

    }

    //优化MVP 处理内存泄漏
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (iPresenter!=null){
            iPresenter.onDetch();
            iPresenter=null;
        }
        //Eventbus注销
        if (EventBus.getDefault().isRegistered(this)){
            EventBus.getDefault().unregister(this);
        }
    }
}

适配器

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> {
    private Context mContext;
    private ArrayList<GoodBean.DataBean> mList;
    //用于判断视图的显示模式
    private Boolean mShow = true;

    public MyRecyclerViewAdapter(Context mContext, ArrayList<GoodBean.DataBean> mList, Boolean mShow) {
        this.mContext = mContext;
        this.mList = mList;
        this.mShow = mShow;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = null;
        //判断要显示的视图
        if (mShow) {
            view = LayoutInflater.from(mContext).inflate(R.layout.item_list, viewGroup, false);
        } else {
            view = LayoutInflater.from(mContext).inflate(R.layout.item_grid, viewGroup, false);
        }
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, final int i) {
        //  Fresco加载图片
        String uris=mList.get(i).getImages();
        String[] split = uris.split("\\|");
        for (int j = 0; j <split.length ; j++) {
            String replace = split[j].replace("https", "http");
            Uri uri=Uri.parse(replace);
            viewHolder.itemImage.setImageURI(uri);
        }

        viewHolder.itemTitle.setText(mList.get(i).getTitle());
        viewHolder.itemPrice.setText("价格:" + mList.get(i).getPrice());
        viewHolder.itemPl.setText("评论数:" + mList.get(i).getSalenum());
        viewHolder.itemImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(mContext, "点击了: " + mList.get(i).getTitle(), Toast.LENGTH_SHORT).show();
                mGoodsClick.onGoodsClick(i);
            }
        });
    }

    @Override
    public int getItemCount() {
        return mList.size();
    }


    static class ViewHolder extends RecyclerView.ViewHolder {
        @BindView(R.id.item_image)
        SimpleDraweeView itemImage;
        @BindView(R.id.item_title)
        TextView itemTitle;
        @BindView(R.id.item_price)
        TextView itemPrice;
        @BindView(R.id.item_pl)
        TextView itemPl;

        ViewHolder(View view) {
            super(view);
            ButterKnife.bind(this, view);
        }
    }

    private goodsClick mGoodsClick;

    public void setGoodsClick(goodsClick goodsClick) {
        mGoodsClick = goodsClick;
    }

    //自定义接口
    public interface goodsClick {
        void onGoodsClick(int position);
    }

}

//详情页

public class WebActivity extends AppCompatActivity {

    @BindView(R.id.web_view)
    WebView webView;
    private String url=null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web);
        ButterKnife.bind(this);
        //注册
        EventBus.getDefault().register(this);
        //支持js语言
        webView.getSettings().setJavaScriptEnabled(true);
        // 缩放至屏幕的大小
        webView.getSettings().setLoadWithOverviewMode(true);
        //支持缩放
        webView.getSettings().setSupportZoom(true);
        /*//取值
        Intent intent = getIntent();
        //获取Intent中的数据
        String url = intent.getStringExtra("url");*/
        //把字符串赋值给输入框
        webView.loadUrl(url);
        //设置用自己的浏览器打开
        webView.setWebViewClient(new MyWebViewClient());
    }

    @Subscribe(threadMode = ThreadMode.MAIN,sticky = true)
    public void getInfo(Object object){
        if (object instanceof String){
            url= (String) object;
        }
    }

    //自定义浏览器
    class MyWebViewClient extends WebViewClient {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return super.shouldOverrideUrlLoading(view, url);
        }
    }

    //预防内存泄露
    @Override
    protected void onPause() {
        super.onPause();
        finish();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (EventBus.getDefault().isRegistered(this)){
            //注销
            EventBus.getDefault().unregister(this);
        }
    }
}

//布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:orientation="horizontal">
        <ImageView
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:src="@drawable/common_nav_btn_back_n_xhdpi"/>
        <SearchView
            android:id="@+id/searchView"
            android:layout_width="0dp"
            android:layout_weight="8"
            android:layout_height="wrap_content"
            android:iconifiedByDefault="false"
            android:queryHint="手机" />
        <ImageView
            android:id="@+id/btn_menu"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:src="@drawable/common_nav_btn_menu_n_xhdpi"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:id="@+id/btn_zonghe"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:background="#fff"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="综合"/>
        <Button
            android:id="@+id/btn_xiaoliang"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:background="#fff"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="销量"/>
        <Button
            android:id="@+id/btn_jiage"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:background="#fff"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="价格"/>
        <Button
            android:id="@+id/shaixuan"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:background="#fff"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="筛选"/>
    </LinearLayout>
    <android.support.v7.widget.RecyclerView
        android:id="@+id/Recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </android.support.v7.widget.RecyclerView>
</LinearLayout>

详情页布局‘

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".WebActivity">

    <WebView
        android:id="@+id/web_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </WebView>
</LinearLayout>

//子布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    xmlns:fresco="http://schemas.android.com/apk/res-auto"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/item_image"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_margin="5dp"
        fresco:placeholderImage="@mipmap/ic_launcher" />
    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/item_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Title"/>
        <TextView
            android:id="@+id/item_price"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="price"/>
        <TextView
            android:id="@+id/item_pl"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="price"/>
    </LinearLayout>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    xmlns:fresco="http://schemas.android.com/apk/res-auto"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal"
    android:orientation="vertical">

    <!--注意命名空间-->
    <!--fresco:placeholderImage="@mipmap/ic_launcher"占位图片-->
    <com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/item_image"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_margin="5dp"
        fresco:placeholderImage="@mipmap/ic_launcher" />
        <TextView
            android:id="@+id/item_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Title"/>
        <TextView
            android:id="@+id/item_price"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="price"/>
        <TextView
            android:id="@+id/item_pl"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="price"/>
</LinearLayout>

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值