Created
March 22, 2015 10:57
-
-
Save shirish87/405dc2cbac67fb3ae177 to your computer and use it in GitHub Desktop.
Stateful Fragment for updating parent Activity on events emitted by Rx.Observable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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