1. 程式人生 > >Android:這是一份非常詳細的MVP+Rxjava2.0+Retrofit2.0相結合舉例RecyclerView的實戰篇章

Android:這是一份非常詳細的MVP+Rxjava2.0+Retrofit2.0相結合舉例RecyclerView的實戰篇章

MVP+Rxjava2.0+Retrofit2.0現在是非常火的組合
MVP相信大家已經在各大網站和各大佬的文章中已經瞭解很多理論的理解了
MVP其實就是M層請求資料 在P層裡進行M層和V層的互動 V層得到資料後展示資料
比如說豺狼媽媽去捕食 捕到食物後回到在窩裡把食物餵給狼寶寶
豺狼媽媽就是M P就是狼窩 V就是狼寶寶
MVP的重點就是介面回撥 不熟悉不瞭解介面回撥的話最好先去學習練習介面回撥

那麼實戰專案中MVP+Rxjava2.0+Retrofit2.0有兩個重要的類

Cantranct:mvp這三個介面的總類 都放在這個類裡 清晰和規範
APIInterface:API介面的總類 Retrofit請求的介面全放在這個裡面


專案整體的分包情況如下:
這裡寫圖片描述 這裡寫圖片描述
下面我是用MVP+Rxjava2.0+Retrofit2.0+RecyclerView詳細的介紹一下

下面程式碼的註釋!非常詳細的標註了每個介面!每個接口裡方法!的作用

網路許可權:

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

依賴:

 //Retrofit的依賴
    compile 'com.squareup.retrofit2:retrofit:2.3.0'
    compile 'com.squareup.okhttp3:okhttp:3.9.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0' compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0' //RxJava2的依賴 compile 'io.reactivex.rxjava2:rxjava:+' compile 'io.reactivex.rxjava2:rxandroid:+' compile 'com.squareup.okhttp3:logging-interceptor:3.9.0' //glide依賴
compile 'com.github.bumptech.glide:glide:3.7.0' //RecyclerView依賴 compile 'com.android.support:recyclerview-v7:26.1.0'

建立api包 建立APIInterface介面

import com.example.mydemo.bean.MyBean;

import io.reactivex.Observable;
import retrofit2.http.GET;

/**
 * Created by wxy on 2017/12/6.
 * API 所有的請求都寫在此類
 */

public interface APIInterface {
    //介面地址
    //String url = "http://api.kkmh.com/v1/daily/comic_lists/0?since=0&gender=0";

    //get請求
    @GET("v1/daily/comic_lists/0?since=0&gender=0")
    Observable<MyBean> getMyData();  //泛型裡的為Bean類
}

建立cantranct包 建立Cantranct類

mport com.example.mydemo.bean.MyBean;

import java.util.List;

/**
 * Created by wxy on 2017/12/6.
 * mvp介面的總類
 */

public class Cantranct {
    //M層介面及方法: 獲取資料
    public interface IModel {
        //M層獲取請求資料的方法 方法引數為下面的介面物件
        void model(CallBack callBack);

        //M層獲取到資料之後 存入這個介面的方法然後把資料回撥給P層
        interface CallBack {
            //方法的引數儲存m層獲取到的資料 然後回撥給P層
            void callData(List<MyBean.DataBean.ComicsBean> comics);
        }
    }

    //P層介面及方法:M和V層的互動等邏輯(其實P層寫不寫介面都可以 用介面顯得統一規範)
    public interface IPresenter {
        void presenter();
    }

    //V層介面 :接收資料 顯示資料
    public interface IView {
        //方法的引數用於接收在P層裡通過M層獲取到的資料
        void view(List<MyBean.DataBean.ComicsBean> comics);
    }

}

建立model包 建立Model類

import com.example.mydemo.api.APIInterface;
import com.example.mydemo.bean.MyBean;
import com.example.mydemo.cantranct.Cantranct;
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;

import java.util.List;

import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Created by wxy on 2017/12/6.
 * M層 請求資料 然後將資料回撥給P層
 */

public class Model implements Cantranct.IModel {
    private String baseUrl = "http://api.kkmh.com/";

    @Override        //這個callback介面就是用來儲存資料 在P層裡把資料給V層的介面
    public void model(final CallBack callBack) {

        Retrofit retrofit = new Retrofit.Builder().baseUrl(baseUrl)//新增baseurl
                //新增Rxjava
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        //建立新增API類
        APIInterface apiInterface = retrofit.create(APIInterface.class);
        //呼叫API中的getMyData請求方法
        apiInterface.getMyData()
                //指定被觀察者執行緒
                .subscribeOn(Schedulers.io())
                //指定觀察者執行緒
                .observeOn(AndroidSchedulers.mainThread())
                //訂閱
                .subscribe(new Observer<MyBean>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(MyBean myBean) {
                        if (myBean != null) {
                            List<MyBean.DataBean.ComicsBean> data = myBean.getData().getComics();
                            myBean.getData().getComics();
                            //請求到資料後 將資料儲存到callback介面的方法裡                
                            //用於將資料回撥給P層 在P層裡將資料給V
                            callBack.callData(data);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }


}

建立presenter包 建立Presenter類

import com.example.mydemo.bean.MyBean;
import com.example.mydemo.cantranct.Cantranct;
import com.example.mydemo.model.Model;

import java.util.List;

/**
 * Created by wxy on 2017/12/6.
 * P層 用於M、V的互動的邏輯 主要將M獲取到的資料 給V
 */

public class Presenter implements Cantranct.IPresenter {
    //建立M層物件
    private Model model;
    //建立V層介面的物件
    private Cantranct.IView iView;

    //構造方法的引數為V層的介面物件
    public Presenter(Cantranct.IView iView) {
        //待會展示資料的類實現V介面 建立P層的時候 將本身傳進來 也就是說P層和展示資料的類他倆使用的是共同的一個V層介面 自然這個V層介面方法裡的資料就可以共用了
        this.iView = iView;
        //建立M層的時候自然執行M層實現的請求資料方法 現在可以理解為已經請求到了資料
        model = new Model();
    }

    @Override//在這個方法裡進行M層和V層的互動
    public void presenter() {
        //M層建立儲存資料的callback介面物件 這個接口裡方法的引數就是資料集合
        model.model(new Cantranct.IModel.CallBack() {
            @Override
            public void callData(List<MyBean.DataBean.ComicsBean> data) {
                //然後再用V層介面物件儲存資料 在V層裡展示出來
                iView.view(data);
            }
        });

    }
}

建立View包 建立Activity類

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

import com.example.mydemo.Adapter.MyAdapter;
import com.example.mydemo.R;
import com.example.mydemo.bean.MyBean;
import com.example.mydemo.cantranct.Cantranct;
import com.example.mydemo.presenter.Presenter;

import java.util.List;

/**
 * V層 從P層得到資料後展示資料
 * 實現V層介面
 */
public class MainActivity extends AppCompatActivity implements Cantranct.IView {

    private RecyclerView recy;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //獲取控制元件
        initView();
        //建立P層物件 傳入本身 因為P層的建構函式是IView介面 而本類實現了IView介面 將本身傳進去之後 在P層進行互動的V介面獲取到資料 在本類實現的V層介面方法裡的資料就可以用了
        Presenter presenter = new Presenter(this);
        presenter.presenter();
    }

    @Override//從P層獲取到的資料  在P層裡獲取到M層請求的資料
    public void view(List<MyBean.DataBean.ComicsBean> data) {
        MyAdapter adapter = new MyAdapter(this, data);
        recy.setAdapter(adapter);
        recy.setLayoutManager(new LinearLayoutManager(this));
    }

    private void initView() {
        recy = (RecyclerView) findViewById(R.id.recy);
    }
}

以上就是整個MVP+Rxjava+Retrofit的實戰結合 練習完或看完程式碼之後 再結合你們所看到過的理論好好捋一捋 或找個筆和紙畫一畫 就能理解的更深點了 下面是RecyclerView的介面卡類 和佈局檔案 想練習這個Demo的可以把下面的複製上去

Bean類就不復制上來了 自己建立吧
activity_main

<RelativeLayout 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"
    tools:context="com.example.mydemo.view.MainActivity">

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

</RelativeLayout>

item

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp">

    <ImageView
        android:id="@+id/im"
        android:layout_width="200dp"
        android:layout_height="150dp"
        android:scaleType="fitXY"
        android:src="@mipmap/ic_launcher" />

    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="15dp"
        android:text="aaaaaa"
        />
</LinearLayout>

MyAdapater

import android.content.Context;
import android.media.Image;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.example.mydemo.R;
import com.example.mydemo.bean.MyBean;

import java.util.List;

/**
 * Created by wxy on 2017/12/6.
 */

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHodel> {
    private Context context;
    private List<MyBean.DataBean.ComicsBean> data = null;

    public MyAdapter(Context context, List<MyBean.DataBean.ComicsBean> data) {
        this.context = context;
        this.data = data;
    }

    @Override
    public MyViewHodel onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = View.inflate(context, R.layout.item, null);
        return new MyViewHodel(view);
    }

    @Override
    public void onBindViewHolder(MyViewHodel holder, int position) {
        Glide.with(context).load(data.get(position).getCover_image_url()).into(holder.im);
        holder.tv.setText(data.get(position).getTopic().getDescription());
    }

    @Override
    public int getItemCount() {
        return data.size() != 0 ? data.size() : 0;
    }

    static class MyViewHodel extends RecyclerView.ViewHolder {

        public final ImageView im;
        public final TextView tv;

        public MyViewHodel(View itemView) {
            super(itemView);
            im = itemView.findViewById(R.id.im);
            tv = itemView.findViewById(R.id.tv);

        }
    }

}

最終效果如下
這裡寫圖片描述