Skip to content

Instantly share code, notes, and snippets.

@shirish87
Created March 22, 2015 10:57
Show Gist options
  • Save shirish87/405dc2cbac67fb3ae177 to your computer and use it in GitHub Desktop.
Save shirish87/405dc2cbac67fb3ae177 to your computer and use it in GitHub Desktop.
Stateful Fragment for updating parent Activity on events emitted by Rx.Observable
package com.apparcadia.common.ui.frag;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.android.app.AppObservable;
import rx.subscriptions.Subscriptions;
import timber.log.Timber;
public abstract class BaseRequestFragment<T, R> extends Fragment {
private static final String TAG = BaseRequestFragment.class.getSimpleName();
private Subscription mSubscription = Subscriptions.empty();
private RequestListener<R> mRequestListener;
private boolean mHasValidArgs;
private int mProgress;
private R mResult;
private Throwable mException;
public BaseRequestFragment() {
super();
setRetainInstance(true);
}
@SuppressWarnings("unchecked")
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof RequestListener) {
try {
mRequestListener = (RequestListener<R>) activity;
} catch (ClassCastException e) {
Timber.e(e, TAG);
throw e;
}
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
mHasValidArgs = processArguments(args);
if (!mHasValidArgs) {
Timber.w("Fragment received invalid arguments");
return;
}
Context context = getActivity().getApplicationContext();
final Subscriber<T> subscriber = createSubscriber(context, args);
mSubscription = AppObservable
.bindFragment(this, createObservable(context, args))
.subscribe(new Subscriber<T>() {
@Override
public void onCompleted() {
if (subscriber != null) {
subscriber.onCompleted();
}
}
@Override
public void onError(Throwable e) {
mException = e;
if (subscriber != null) {
subscriber.onError(e);
}
notifyListener();
}
@Override
public void onNext(T t) {
mProgress = processProgress(t);
mResult = transformResult(t);
if (subscriber != null) {
subscriber.onNext(t);
}
notifyListener();
}
});
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
notifyListener();
}
protected int processProgress(T t) {
return 0;
}
protected void notifyListener() {
if (mRequestListener != null) {
if (mException != null) {
// Error \/ Success
mRequestListener.onError(mException);
} else {
if (mResult != null) {
// We already have the result
mRequestListener.onSuccess(mResult);
} else if (mProgress > 0) {
// We're in progress
mRequestListener.onProgress(mProgress);
}
}
}
}
@Override
public void onDestroy() {
mSubscription.unsubscribe();
super.onDestroy();
}
public boolean hasValidArgs() {
return mHasValidArgs;
}
public int getProgress() {
return mProgress;
}
public R getResult() {
return mResult;
}
public Throwable getException() {
return mException;
}
protected Subscriber<T> createSubscriber(Context context, Bundle args) {
// in case a child would like to tap into the Observable
return null;
}
protected abstract boolean processArguments(Bundle args);
protected abstract Observable<T> createObservable(Context context, Bundle args);
protected abstract R transformResult(T t);
public interface RequestListener<R> {
public void onProgress(int progress);
public void onError(Throwable e);
public void onSuccess(R data);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment