在我看来,RxJava最大的特点就是异步,无论你是解析复杂的数据或是IO操作,我们都可以利用它内置的线程池进行线程间的调度,简单的使用
subscribeOn(Schedulers.io()).doOnNext(...)
observeOn(AndroidSchedulers.mainThread()).doOnNext(...)
这种操作就可以指定操作在你想要的线程里执行.
当然,网络请求这种耗时的操作肯定也是要放在子线程执行的,那么是异步操作,我们就会有等待时间,安卓里通常的做法是在界面上盖一个加载中的loading;等操作完成,切换到UI线程时,我们再把它隐藏起来.
于是有
private final HomeContract.View mView;
retrofit.create(ApiService.class)
.getHomeData(loginCallInfo.getAccessToken(), loginCallInfo.getUserId(), Constants.PLATFORM, Constants.APPLICATIONID, 1)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<HomeData>() {
@Override
public void onSubscribe(Disposable d) {
if (!d.isDisposed()) {
mView.setLoadingView();
}
}
@Override
public void onNext(HomeData value) {
if (value == null) {
mView.setEmptyView();
} else {
mView.setSuccessView();
...//这里显示正常视图
}
}
@Override
public void onError(Throwable t) {
Logger.d(t.getMessage());
mView.setErrorView();
}
@Override
public void onComplete() {
}
});
在HomeContract.java中
public class HomeContract {
interface View extends BaseView<Presenter> {
void setLoadingView();
void setSuccessView();
void setErrorView();
void setEmptyView();
}
}
具体在HomeFragment里的实现
@Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View root =inflater.inflate(R.layout.fragment_home,container,false); progress = (ProgressBar) root.findViewById(R.id.loading);
fl_excep = (FrameLayout) root.findViewById(R.id.fl_error);
retry = ((Button) root.findViewById(R.id.btn_retry));
retry.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Logger.e("正在重试");//重试操作 } }); } @Override public void setLoadingView() { if (progress.getVisibility() == View.GONE) { progress.setVisibility(View.VISIBLE); } } @Override public void setSuccessView() { if (progress.getVisibility() == View.VISIBLE) { progress.setVisibility(View.GONE); } } @Override public void setErrorView() { if (progress.getVisibility() == View.VISIBLE) { progress.setVisibility(View.GONE); fl_excep.setVisibility(View.VISIBLE); retry.setText(R.string.request_err); } } @Override public void setEmptyView() { if (progress.getVisibility() == View.VISIBLE) { progress.setVisibility(View.GONE); fl_excep.setVisibility(View.VISIBLE); retry.setText(R.string.empty_des); } }
最后,看下xml布局
fragment_home.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/translucent">
<--这里是你想显示的正常视图-->
<include layout="@layout/public_loading" />
</FrameLayout>
public_loading.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
<FrameLayout
android:id="@+id/fl_error"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
<Button
android:id="@+id/btn_retry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@null"
android:text="网络错误,点击重试"
android:textSize="20sp" />
</FrameLayout>
</FrameLayout>
这样,一个控制加载状态的功能就写完了.