在我看来,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>
这样,一个控制加载状态的功能就写完了.