1. 程式人生 > >MVP+RecyclerView+SmartRefreshLayout 實現重新整理載入

MVP+RecyclerView+SmartRefreshLayout 實現重新整理載入

一、view層介面 (IView)

package com.xwj.lenovo.my_mvp_two.view;

/**
 * Created by lenovo on 2018/5/7.
 */

public interface IView {
    void getSuccess(String string);

    void getError(String error);
}

二、IPresenter層

1.(IPresenter)介面

package com.xwj.lenovo.my_mvp_two.presenter;

import java.util.Map;

/**
 * Created by lenovo on 2018/5/7.
 */
public interface IPresenter { //成功的 void getSuccess(String string); //失敗的 void getError(String error); //獲取資料 void getData(String url, Map<String, String> map); }

2.IPresenter的實現類 (IPresenterImpI)

package com.xwj.lenovo.my_mvp_two.presenter;

import com.xwj.lenovo.my_mvp_two.model.IModelmpI;
import
com.xwj.lenovo.my_mvp_two.view.IView; import java.util.Map; /** * Created by lenovo on 2018/5/7. */ public class IPresenterImpI implements IPresenter { private IView iView; private final IModelmpI iModelmpI; //有參構造 public IPresenterImpI(IView iView) { //例項化model類 iModelmpI = new
IModelmpI(this); this.iView = iView; } //成功的 @Override public void getSuccess(String string) { iView.getSuccess(string); } //失敗的 @Override public void getError(String error) { iView.getError(error); } //獲取資料 @Override public void getData(String url, Map<String, String> map) { iModelmpI.getData(url, map); } }

三、model層

1、model層介面 (IModel)

package com.xwj.lenovo.my_mvp_two.model;

import java.util.Map;

/**
 * Created by lenovo on 2018/5/7.
 */

public interface IModel {
    void getData(String url, Map<String,String> map);
}

2.model層的實現類 (IModelmpI )

注意:下面 判斷時根據自己的bean類,去決定要判斷的值,我這裡是狀態,狀態為false時,獲取資料,一般大部分都是code=0為成功,不要寫錯呦!

package com.xwj.lenovo.my_mvp_two.model;

import android.util.Log;

import com.xwj.lenovo.my_mvp_two.http.RetrofitUtils;
import com.xwj.lenovo.my_mvp_two.presenter.IPresenter;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.Map;

import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;

/**
 * Created by lenovo on 2018/5/7.
 */

public class IModelmpI implements IModel {
    IPresenter iPresenter;

    //構造方法
    public IModelmpI(IPresenter iPresenter) {
        this.iPresenter = iPresenter;
    }

    @Override
    public void getData(String url, Map<String, String> map) {
        RetrofitUtils.getService().getDataGetView(url,map)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(new Observer<ResponseBody>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(ResponseBody responseBody) {
                        try {
                            String string = responseBody.string();
                            try {
                                JSONObject jsonObject = new JSONObject(string);
                                String error = jsonObject.getString("error");
                                //判斷狀態為false時,獲取資料------》根據自己的bean類決定自己要判斷的引數
                                if ("false".equals(error)){
                                    iPresenter.getSuccess(string);
                                }else {
                                    //失敗的回撥
                                    iPresenter.getError(string);
                                }
                            } catch (JSONException e) {
                                e.printStackTrace();
                                //失敗的回撥
                                iPresenter.getError(string);
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d("IModelmpI", "出現異常----------------------"+e.getMessage());
                    }

                    @Override
                    public void onComplete() {

                    }
                });

    }
}

四、需要用到的 ApiService

裡面是需要用到的兩種請求方式

package com.xwj.lenovo.my_mvp_two.http;

import java.util.Map;

import io.reactivex.Observable;
import okhttp3.ResponseBody;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Path;
import retrofit2.http.QueryMap;

/**
 * Created by lenovo on 2018/5/7.
 */

public interface ApiService {

    //get請求
    @GET("{url}")
    Observable<ResponseBody> getDataGetView(@Path(value = "url", encoded = true) String url, @QueryMap Map<String, String> map);

    //Post請求
    @FormUrlEncoded
    @POST("{url}")
    Observable<ResponseBody> getDataPostView(@Path(value = "url", encoded = true) String url, @FieldMap Map<String, String> map);
}

五、RetrofitUtils 工具類

package com.xwj.lenovo.my_mvp_two.http;


import android.util.Log;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import okhttp3.FormBody;
import okhttp3.Interceptor;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Created by Administrator on 2018/4/9 0009.
 */

public class RetrofitUtils {
    private Retrofit retrofit;
    private static RetrofitUtils retrofitUtils = null;

    public RetrofitUtils() {

    }


    public RetrofitUtils(String baseUrl) {
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(new CommonParamsInterceptor())
                .build();

        retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();

    }

    public static RetrofitUtils getInstance(String baseUrl) {
        if (retrofitUtils == null) {
            synchronized (RetrofitUtils.class) {
                if (retrofitUtils == null) {
                    retrofitUtils = new RetrofitUtils(baseUrl);
                }
            }
        }
        return retrofitUtils;
    }

    public <T> T createService(Class<T> service) {
        return retrofit.create(service);
    }

    public static ApiService getService() {
        return RetrofitUtils.getInstance(HttpConfig.base_url).createService(ApiService.class);
    }

    //攔截器
    public class CommonParamsInterceptor implements Interceptor {

        @Override
        public Response intercept(Chain chain) throws IOException {
            //呼叫request()方法得到攔截的請求
            Request request = chain.request();
            //獲取請求的方式
            String method = request.method();//GET POST
            //攔截的請求的路徑
            String oldUrl = request.url().toString();
            Log.e("----oldUrl", oldUrl);
            //要新增的公共引數...map
            Map<String, String> map = new HashMap<>();
            map.put("source", "android");
            map.put("appVersion", "100");
            if ("GET".equals(method)) {
                StringBuilder stringBuilder = new StringBuilder();//建立一個stringBuilder...字串緩衝區
                stringBuilder.append(oldUrl);
                if (oldUrl.contains("?")) {
                    //?在最後面....2型別
                    if (oldUrl.indexOf("?") == oldUrl.length() - 1) {

                    } else {
                        //3型別...拼接上&
                        stringBuilder.append("&");
                    }
                } else {
                    //不包含? 屬於1型別,,,先拼接上?號
                    stringBuilder.append("?");
                }
                //新增公共引數....source=android&appVersion=100&
                for (Map.Entry<String, String> entry : map.entrySet()) {
                    //拼接
                    stringBuilder.append(entry.getKey())
                            .append("=")
                            .append(entry.getValue())
                            .append("&");
                }
                //刪掉最後一個&符號
                if (stringBuilder.indexOf("&") != -1) {
                    stringBuilder.deleteCharAt(stringBuilder.lastIndexOf("&"));
                }
                //得到含有公共引數的新路徑.....使用新路徑去請求
                String newUrl = stringBuilder.toString();
                Log.e("----newUrl", newUrl);
                //新的路徑構建一個新的請求
                request = request.newBuilder().url(newUrl).build();
            } else if ("POST".equals(method)) {
                //引數在請求的實體內容上....拿到以前的引數,把以前的引數和公共引數全都新增到請求實體上
                RequestBody requestBody = request.body();
                if (requestBody instanceof FormBody) {//前邊是不是後邊的子類/例項物件
                    FormBody oldBody = (FormBody) requestBody;//keywords...page
                    FormBody.Builder builder = new FormBody.Builder();
                    //先新增之前的引數
                    for (int i = 0; i < oldBody.size(); i++) {
                        //鍵值對的形式新增
                        builder.add(oldBody.name(i), oldBody.value(i));
                    }
                    //新增公共引數
                    for (Map.Entry<String, String> entry : map.entrySet()) {
                        builder.add(entry.getKey(), entry.getValue());
                    }
                    //構建一個新的請求
                    request = request.newBuilder().url(oldUrl).post(builder.build()).build();
                } else if (request.body() instanceof MultipartBody) {
                    MultipartBody body = (MultipartBody) request.body();
                    MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
                    builder.addFormDataPart("source", "android")
                            .addFormDataPart("appVersion", "101");
                    List<MultipartBody.Part> parts = body.parts();
                    for (MultipartBody.Part part : parts) {
                        builder.addPart(part);
                    }
                    request = request.newBuilder().url(oldUrl).post(builder.build()).build();
                }

            }
            //執行請求 獲取到響應
            Response response = chain.proceed(request);
            return response;
        }
    }
}

六、MainActivity的佈局

<?xml version="1.0" encoding="utf-8"?>
<com.scwang.smartrefresh.layout.SmartRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/refreshLayout"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.xwj.lenovo.my_mvp_two.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recy_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>

</com.scwang.smartrefresh.layout.SmartRefreshLayout>

七、MainActivity中做的具體操作

package com.xwj.lenovo.my_mvp_two;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;

import com.google.gson.Gson;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.listener.OnLoadmoreListener;
import com.scwang.smartrefresh.layout.listener.OnRefreshListener;
import com.xwj.lenovo.my_mvp_two.adpter.MyRecylerView;
import com.xwj.lenovo.my_mvp_two.bean.MyBean;
import com.xwj.lenovo.my_mvp_two.http.HttpConfig;
import com.xwj.lenovo.my_mvp_two.presenter.IPresenterImpI;
import com.xwj.lenovo.my_mvp_two.view.IView;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import butterknife.BindView;
import butterknife.ButterKnife;

public class MainActivity extends AppCompatActivity implements IView {

    int page = 1;
    @BindView(R.id.recy_view)
    RecyclerView recyView;
    @BindView(R.id.refreshLayout)
    com.scwang.smartrefresh.layout.SmartRefreshLayout refreshLayout;
    private IPresenterImpI iPresenterImpI;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        //佈局管理器
        recyView.setLayoutManager(new LinearLayoutManager(this));
        //呼叫MVP
        iPresenterImpI = new IPresenterImpI(this);
        //獲取資料的方法
        initview();
    }

    private void initview() {
        Map<String, String> map = new HashMap<>();
        iPresenterImpI.getData(HttpConfig.data_url + page, map);
    }

    /**
     * 重寫的view 層的方法
     * @param string
     */
    @Override
    public void getSuccess(String string) {
        MyBean myBean = new Gson().fromJson(string, MyBean.class);
        List<MyBean.ResultsBean> list = myBean.getResults();
        MyRecylerView myRecylerView = new MyRecylerView(this, list);
        recyView.setAdapter(myRecylerView);
        //SmartRefreshLayout控制元件的重新整理
        refreshLayout.setOnRefreshListener(new OnRefreshListener() {
            @Override
            public void onRefresh(RefreshLayout refreshlayout) {
                page = 1;
                //重新載入資料
                initview();
                //3秒以後關閉重新整理的檢視
                refreshlayout.finishRefresh(4000);
            }
        });

        //SmartRefreshLayout控制元件的載入
        refreshLayout.setOnLoadmoreListener(new OnLoadmoreListener() {
            @Override
            public void onLoadmore(RefreshLayout refreshlayout) {
                //頁數++   進行載入下一頁
                page++;
                //重新載入資料
                initview();
                //3秒以後關閉載入的檢視
                refreshlayout.finishLoadmore(3000);
            }
        });
    }

    //失敗的方法
    @Override
    public void getError(String error) {
        Log.d("MainActivity", "失敗啦!-----》"+error);
    }

}

接下來就是寫介面卡了,我用的是RecyclerView,相信RecyclerView的介面卡大家都會寫的,這裡就不貼出來啦!
這樣一個通過mvp框架+RecyclerView展示資料+第三方控制元件SmartRefreshLayout進行重新整理的小demo就完成啦!

對了,小夥伴們不要忘記加許可權哦!

效果基本就是下面這樣:

這裡寫圖片描述

這裡寫圖片描述