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详细的介绍一下
接口:http://api.kkmh.com/v1/daily/comic_lists/0?since=0&gender=0
下面代码的注释!非常详细的标注了每个接口!每个接口里方法!的作用
网络权限:
<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);
}
}
}
最终效果如下
不要看那么多理论 要练 就算自己独自摸索练 慢慢也就理清楚了
下面是Rxjava和Retrofit的链接
Retrofir2.0的简单使用
Rxjava
Rxjava2.0和Retrofit2.0结合使用