1. 程式人生 > >RxJava非同步請求載入狀態控制

RxJava非同步請求載入狀態控制

在我看來,RxJava最大的特點就是非同步,無論你是解析複雜的資料或是IO操作,我們都可以利用它內建的執行緒池進行執行緒間的排程,簡單的使用

當然,網路請求這種耗時的操作肯定也是要放在子執行緒執行的,那麼是非同步操作,我們就會有等待時間,安卓裡通常的做法是在介面上蓋一個載入中的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>

這樣,一個控制載入狀態的功能就寫完了.