Skip to content

Commit

Permalink
Introduce HistoryCallback
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergey Petukhov committed Sep 12, 2017
1 parent 79c2df1 commit 4980cef
Show file tree
Hide file tree
Showing 13 changed files with 345 additions and 192 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ public class BasicSampleActivity extends Activity {
}

@Override public void onBackPressed() {
if (!Flow.get(this).goBack()) {
super.onBackPressed();
}
Flow.get(this).goBack();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,21 @@
import android.app.Activity;
import android.content.Context;
import flow.Flow;
import flow.HistoryCallback;

public class HelloWorldActivity extends Activity {
public class HelloWorldActivity extends Activity implements HistoryCallback {

@Override protected void attachBaseContext(Context baseContext) {
baseContext = Flow.configure(baseContext, this).install();
baseContext = Flow.configure(baseContext, this).historyCallback(this).install();
super.attachBaseContext(baseContext);
}

@Override public void onBackPressed() {
if (!Flow.get(this).goBack()) {
super.onBackPressed();
}
Flow.get(this).goBack();
}

@Override
public void onHistoryCleared() {
super.onBackPressed();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import android.app.Activity;
import android.content.Context;
import android.content.Intent;

import flow.Flow;

public class IntentsSingleInstanceSampleActivity extends Activity {
Expand All @@ -33,8 +34,6 @@ public class IntentsSingleInstanceSampleActivity extends Activity {
}

@Override public void onBackPressed() {
if (!Flow.get(this).goBack()) {
super.onBackPressed();
}
Flow.get(this).goBack();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import android.app.Activity;
import android.content.Context;

import flow.Flow;

public class IntentsStandardSampleActivity extends Activity {
Expand All @@ -28,8 +29,6 @@ public class IntentsStandardSampleActivity extends Activity {
}

@Override public void onBackPressed() {
if (!Flow.get(this).goBack()) {
super.onBackPressed();
}
Flow.get(this).goBack();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ public class MultiKeySampleActivity extends AppCompatActivity {
}

@Override public void onBackPressed() {
if (!getFlow().goBack()) {
super.onBackPressed();
}
getFlow().goBack();
}

private final class Changer implements KeyChanger {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;

import flow.Flow;

public class OrientationSampleActivity extends Activity {
Expand All @@ -37,8 +38,6 @@ public class OrientationSampleActivity extends Activity {
}

@Override public void onBackPressed() {
if (!Flow.get(this).goBack()) {
super.onBackPressed();
}
Flow.get(this).goBack();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,7 @@ public class TreeSampleActivity extends AppCompatActivity {
}

@Override public void onBackPressed() {
if (!Flow.get(this).goBack()) {
super.onBackPressed();
}
Flow.get(this).goBack();
}

private final class Changer implements KeyChanger {
Expand Down
54 changes: 35 additions & 19 deletions flow/src/main/java/flow/Flow.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import android.support.annotation.Nullable;
import android.view.View;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

Expand Down Expand Up @@ -119,6 +120,7 @@ public static void addHistory(@NonNull Intent intent, @NonNull History history,
private HistoryFilter historyFilter = new NotPersistentHistoryFilter();
private Dispatcher dispatcher;
private PendingTraversal pendingTraversal;
private HistoryCallback historyCallback;
private List<Object> tearDownKeys = new ArrayList<>();
private final KeyManager keyManager;

Expand Down Expand Up @@ -179,6 +181,10 @@ void setDispatcher(@NonNull Dispatcher dispatcher, final boolean restore) {
}
}

void setHistoryCallback(@NonNull HistoryCallback historyCallback) {
this.historyCallback = historyCallback;
}

/**
* Remove the dispatcher. A noop if the given dispatcher is not the current one.
* <p>
Expand Down Expand Up @@ -282,30 +288,27 @@ public void set(@NonNull final Object newTopKey) {
}

/**
* Go back one key. Typically called from {@link Activity#onBackPressed()}, with
* the return value determining whether or not to call super. E.g.
* <pre>
* public void onBackPressed() {
* if (!Flow.get(this).goBack()) {
* super.onBackPressed();
* }
* }
* </pre>
*
* @return false if going back is not possible.
* Go back one key. Typically called from {@link Activity#onBackPressed()}.
* If there is no way to go back, {@link HistoryCallback#onHistoryCleared()} would be triggered.
* Use {@link Installer#historyCallback(HistoryCallback)} to provide your own
* clearHistory implementation. By default, {@link Activity#finish()} would be called.
*/
@CheckResult public boolean goBack() {
public void goBack() {
boolean canGoBack = history.size() > 1 || (pendingTraversal != null
&& pendingTraversal.state != TraversalState.FINISHED);
if (!canGoBack) return false;
if (!canGoBack) {
historyCallback.onHistoryCleared();
return;
}

move(new PendingTraversal() {
@Override void doExecute() {
if (history.size() <= 1) {
// The history shrank while this op was pending. It happens, let's
// no-op. See lengthy discussions:
// https://github.com/square/flow/issues/195
// https://github.com/square/flow/pull/197
if (history.size() == 0) {
throw new IllegalStateException("goBack() on empty history");
}
if (history.size() == 1) {
// https://github.com/square/flow/issues/264
pendingTraversal.clearHistory();
return;
}

Expand All @@ -315,7 +318,6 @@ public void set(@NonNull final Object newTopKey) {
dispatch(newHistory, Direction.BACKWARD);
}
});
return true;
}

private void move(PendingTraversal pendingTraversal) {
Expand Down Expand Up @@ -438,6 +440,20 @@ final void execute() {
doExecute();
}

final void clearHistory() {
// Note: history top will be cleared in onDestroy() call
final Iterator<Object> it = tearDownKeys.iterator();
while (it.hasNext()) {
keyManager.tearDown(it.next());
it.remove();
}
keyManager.clearStatesExcept(Collections.emptyList());
next = null;
pendingTraversal = null;
state = TraversalState.FINISHED;
historyCallback.onHistoryCleared();
}

/**
* Must be synchronous and end with a call to {@link #dispatch} or {@link
* #onTraversalCompleted()}.
Expand Down
17 changes: 17 additions & 0 deletions flow/src/main/java/flow/HistoryCallback.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package flow;

import android.app.Activity;

/**
* History callback, should be implemented to track history events.
*
* @author sdelaysam
*/

public interface HistoryCallback {
/**
* Called by Flow when history cleared.
* Default implementation would call {@link Activity#finish()}
*/
void onHistoryCleared();
}
18 changes: 17 additions & 1 deletion flow/src/main/java/flow/Installer.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public final class Installer {
private KeyParceler parceler;
private Object defaultKey;
private Dispatcher dispatcher;
private HistoryCallback historyCallback;

Installer(Context baseContext, Activity activity) {
this.baseContext = baseContext;
Expand All @@ -53,6 +54,11 @@ public final class Installer {
return this;
}

@NonNull public Installer historyCallback(@Nullable HistoryCallback historyCallback) {
this.historyCallback = historyCallback;
return this;
}

/**
* Applies a factory when creating a Context associated with a given key.
*
Expand All @@ -73,13 +79,23 @@ public final class Installer {
dispatcher = KeyDispatcher.configure(activity, new DefaultKeyChanger(activity)) //
.build();
}
HistoryCallback historyCallback = this.historyCallback;
if (historyCallback == null) {
historyCallback = new HistoryCallback() {
@Override
public void onHistoryCleared() {
activity.finish();
}
};
}

final Object defState = defaultKey == null ? "Hello, World!" : defaultKey;

final History defaultHistory = History.single(defState);
final Application app = (Application) baseContext.getApplicationContext();
final KeyManager keyManager = new KeyManager(contextFactories);
InternalLifecycleIntegration.install(app, activity, parceler, defaultHistory, dispatcher,
keyManager);
keyManager, historyCallback);
return new InternalContextWrapper(baseContext, activity);
}
}
7 changes: 6 additions & 1 deletion flow/src/main/java/flow/InternalLifecycleIntegration.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ public final class InternalLifecycleIntegration extends Fragment {

static void install(final Application app, final Activity activity,
@Nullable final KeyParceler parceler, final History defaultHistory,
final Dispatcher dispatcher, final KeyManager keyManager) {
final Dispatcher dispatcher, final KeyManager keyManager,
final HistoryCallback historyCallback) {
app.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
@Override public void onActivityCreated(Activity a, Bundle savedInstanceState) {
if (a == activity) {
Expand All @@ -69,6 +70,8 @@ static void install(final Application app, final Activity activity,
}
// We always replace the dispatcher because it frequently references the Activity.
fragment.dispatcher = dispatcher;
// Same with history callback, most likely it will reference the Activity
fragment.historyCallback = historyCallback;
fragment.intent = a.getIntent();
if (newFragment) {
activity.getFragmentManager() //
Expand Down Expand Up @@ -106,6 +109,7 @@ static void install(final Application app, final Activity activity,
History defaultHistory;
Dispatcher dispatcher;
Intent intent;
HistoryCallback historyCallback;
private boolean dispatcherSet;

public InternalLifecycleIntegration() {
Expand Down Expand Up @@ -150,6 +154,7 @@ void onNewIntent(Intent intent) {
} else {
flow.setDispatcher(dispatcher, true);
}
flow.setHistoryCallback(historyCallback);
dispatcherSet = true;
}

Expand Down
Loading

0 comments on commit 4980cef

Please sign in to comment.