package flow.sample.multikey; import android.app.Activity; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.TextView; import flow.Direction; import flow.Flow; import flow.KeyChanger; import flow.KeyDispatcher; import flow.State; import flow.TraversalCallback; import java.util.Map; /** * Demonstrates MultiKeys, e.g. screens with dialogs. */ public class MultiKeySampleActivity extends AppCompatActivity { @Override protected void attachBaseContext(Context baseContext) { baseContext = Flow.configure(baseContext, this) .dispatcher(KeyDispatcher.configure(this, new Changer()).build()) .defaultKey(new ScreenOne()) .install(); super.attachBaseContext(baseContext); } @Override public void onBackPressed() { if (!getFlow().goBack()) { super.onBackPressed(); } } private final class Changer implements KeyChanger { Dialog visibleDialog; @Override public void changeKey(@Nullable State outgoingState, @NonNull State incomingState, @NonNull Direction direction, @NonNull Map<Object, Context> incomingContexts, @NonNull TraversalCallback callback) { final Object mainKey; final Object dialogKey; final Object showThis = incomingState.getKey(); if (showThis instanceof DialogScreen) { mainKey = ((DialogScreen) showThis).mainContent; dialogKey = showThis; } else { mainKey = showThis; dialogKey = null; } final TextView mainView = new TextView(incomingContexts.get(mainKey)); if (mainKey instanceof ScreenOne) { mainView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { getFlow().set(new DialogScreen(mainKey)); } }); } else { mainView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { getFlow().set(new ScreenOne()); } }); } mainView.setText(mainKey.toString()); setContentView(mainView); dismissOldDialog(); if (dialogKey != null) { visibleDialog = new AlertDialog.Builder(incomingContexts.get(dialogKey)) // .setNegativeButton("No", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { getFlow().goBack(); } }) // .setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialogInterface) { getFlow().goBack(); } }) // .setPositiveButton("Yes", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { getFlow().set(new ScreenTwo()); // In real life you'd be more likely to do something like this, // to prevent the dialog from showing up again when the back // button is hit. // //final History.Builder newHistory = getFlow().getHistory().buildUpon(); //newHistory.pop(); // drop the dialog //newHistory.push(new ScreenTwo()); //getFlow().setHistory(newHistory.build(), Flow.Direction.FORWARD); } }) // .setTitle(dialogKey.toString()) // .show(); // Prevent logging of android.view.WindowLeaked. getApplication().registerActivityLifecycleCallbacks(new ActivityLifecycleCallbackAdapter() { @Override public void onActivityDestroyed(Activity activity) { getApplication().unregisterActivityLifecycleCallbacks(this); dismissOldDialog(); } }); } callback.onTraversalCompleted(); } private void dismissOldDialog() { if (visibleDialog != null) { visibleDialog.dismiss(); visibleDialog = null; } } } private Flow getFlow() { return Flow.get(MultiKeySampleActivity.this); } }