实现功能:
网络数据请求,缓存,等待窗口,刷新加载,recyclerview封装。
知识点:
Rxjava2+retrofit2+okhttp3网路请求,Glide图片加载,recyclerview使用,自定义控件。
网络结构图:
使用说明:
导入包
清单文件
注意关联MyApplication,并用自己的application继承,这里用RxApp继承
其它
加载刷新用values文件下attrs.xml
主类RxjavaActivity
public class RxjavaActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private RecyclerView mRecyclerView;
// private TextView mTextView;
private CommonAdapter commonadapter;
private SwipyRefreshLayout swipeRefreshLayout;
private Dialog loading_dialog;
private List storiesList;
private final int TOP_REFRESH = 1;
private final int BOTTOM_REFRESH = 2;
int start=0; //开始请求位置
int pages=10; //需要请求的数据数量
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rxjava);
initView();
dataView(start,pages);
setListener();
}
private void initView() {
storiesList=new ArrayList<>();
swipeRefreshLayout = (SwipyRefreshLayout) findViewById(R.id.swipeRefreshLayout);
mRecyclerView = (RecyclerView)findViewById(R.id.id_stickynavlayout_innerscrollview);
mRecyclerView.setLayoutManager(new GridLayoutManager(this,2));
loading_dialog = new AlertDialog.Builder(this).setMessage("loading...").create();
commonadapter = new CommonAdapter(this,R.layout.rxjava_grid_item,storiesList) {
@Override
public void convert(ViewHolder holder, RxMovieBean.SubjectsBean subjectsBean) {
ImageView imgview=holder.getView(R.id.imageIv);
Glide.with(holder.itemView.getContext())
.load(subjectsBean.getImages().getLarge()).into(imgview);
holder.setText(R.id.descriptionTv,subjectsBean.getTitle());
}
};
mRecyclerView.setAdapter(commonadapter);
commonadapter.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(ViewGroup parent, View view, Object o, int position) {
Toast.makeText(RxjavaActivity.this, "位置"+position, Toast.LENGTH_SHORT).show();
}
@Override
public boolean onItemLongClick(ViewGroup parent, View view, Object o, int position) {
return false;
}
});
}
/**
*调用说明
* 1.调用RxSingleRxHttp
* 2.关联url
* 3.开启缓存
* 4.读取时间
* 5.关联api接口
* 6.api接口中具体内容
* 7.添加分支,等待框
* 8.订阅
* */
private void dataView(int start,int pag) {
RxHttpUtils.getSInstance()
.baseUrl(RxUrl.BASE_URL)
.cache(true)
.readTimeout(500)
.createSApi(Rxdoubanapi.class)
.fetchMovieTop250(start, pag)
.compose(RxTransformer.switchSchedulers(loading_dialog))
.subscribe(new RxCommonObserver(loading_dialog) {
@Override
protected void getDisposable(Disposable d) {
}
@Override
protected void onError(String errorMsg) {
}
@Override
protected void onSuccess(RxMovieBean eMovieBean) {
storiesList.addAll(eMovieBean.getSubjects());
commonadapter.notifyDataSetChanged();
showToast("请求成功");
}
});
}
private void setListener() {
swipeRefreshLayout.setOnRefreshListener(new SwipyRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh(int index) {
Log.i(TAG, "onRefresh: "+index);
dataOption(TOP_REFRESH);
}
@Override
public void onLoad(int index) {
Log.i(TAG, "onLoad: "+index);
dataOption(BOTTOM_REFRESH);
}
});
}
private void dataOption(int option){
switch (option) {
case TOP_REFRESH:
pages=10;
dataView(0,pages);
storiesList.clear();
break;
case BOTTOM_REFRESH:
if(start>30){
Toast.makeText(RxjavaActivity.this, "到头了亲", Toast.LENGTH_SHORT).show();
}else{
start=start+10;
dataView(start,pages);
}
break;
}
swipeRefreshLayout.setRefreshing(false);
commonadapter.notifyDataSetChanged();
}
}
被观察者核心代码:
public class RxRetrofitClient {
private static RxRetrofitClient instance;
private Retrofit.Builder mRetrofitBuilder;
private OkHttpClient.Builder mOkHttpBuilder;
public RxRetrofitClient() {
mOkHttpBuilder = new OkHttpClient.Builder();
mRetrofitBuilder = new Retrofit.Builder()
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(mOkHttpBuilder.build());
}
public static RxRetrofitClient getInstance() {
if (instance == null) {
synchronized (RxRetrofitClient.class) {
if (instance == null) {
instance = new RxRetrofitClient();
}
}
}
return instance;
}
public Retrofit.Builder getRetrofitBuilder() {
return mRetrofitBuilder;
}
public Retrofit getRetrofit() {
return mRetrofitBuilder.client(mOkHttpBuilder.build()).build();
}
}
观察者核心代码:
public abstract class RxBaseObserver implements Observer, RxISubscriber {
private Toast mToast;
public static final String errorMsg_SocketTimeoutException = "网络链接超时,请检查您的网络状态,稍后重试!";
public static final String errorMsg_ConnectException = "网络链接异常,请检查您的网络状态";
public static final String errorMsg_UnknownHostException = "网络异常,请检查您的网络状态";
protected void doOnNetError() {
}
@Override
public void onSubscribe(@NonNull Disposable d) {
doOnSubscribe(d);
}
@Override
public void onNext(@NonNull T t) {
doOnNext(t);
}
@Override
public void onError(@NonNull Throwable e) {
if (e instanceof SocketTimeoutException) {
setError(errorMsg_SocketTimeoutException);
} else if (e instanceof ConnectException) {
setError(errorMsg_ConnectException);
} else if (e instanceof UnknownHostException) {
setError(errorMsg_UnknownHostException);
} else {
String error = e.getMessage();
showToast(error);
doOnError(error);
}
}
@Override
public void onComplete() {
doOnCompleted();
}
private void setError(String errorMsg) {
showToast(errorMsg);
doOnError(errorMsg);
doOnNetError();
}
/**
* Toast提示
*
* @param msg 提示内容
*/
protected void showToast(String msg) {
if (mToast == null) {
mToast = Toast.makeText(RxApp.getInstance(), msg, Toast.LENGTH_SHORT);
} else {
mToast.setText(msg);
}
mToast.show();
}
/**
* 错误处理
*
* @param e
* @return
*/
private String handleError(Throwable e) {
String error = null;
try {
ResponseBody errorBody = ((HttpException) e).response().errorBody();
error = errorBody.string();
} catch (IOException e1) {
e1.printStackTrace();
}
return error;
}
}
具体实现请看源码
补充:BaseObserver中的T可继承BaseResponse对code和msg同一处理,处理地点在BaseObserver的onNext中。
注意:Gilde4.0-RC1可能出现图片加载异常,替换Gilde4.0可修复
参考:
Rxjava2 学习(九篇容易理解)good
Rxjava1学习(大神级教程)good
封装完整版
okhttp