diff --git a/CHANGELOG.md b/CHANGELOG.md index 59cd56f4..53af1e25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Change log +-Simple Stack 1.1.0 (2017-02-18) +-------------------------------- +- BREAKING CHANGE: `Backstack`'s APIs return `Object` instead of `Parcelable` (that includes `StateChange`, initial keys, `HistoryBuilder`, etc.) + +- ENHANCEMENT: Added `KeyParceler` interface to allow defining custom strategy in order to turn keys into `Parcelable` (for example, using `Parceler` library instead) + -Simple Stack 1.0.0 (2017-02-15) -------------------------------- - RELEASE: 1.0.0! diff --git a/README.md b/README.md index 4f5c8580..1d36798b 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ # Simple Stack -Similarly to [square/flow](https://github.com/square/flow), Simple Stack allows you to represent your application state in a list of immutable (and parcelable) data classes. +Similarly to [square/flow](https://github.com/square/flow), Simple Stack allows you to represent your application state in a list of immutable data classes. The library also provides you with the means of persisting the backstack easily through a delegate class, which handles both configuration change and process death. +If your data classes are not `Parcelable` by default, then you can specify a custom parcellation strategy using `backstackDelegate.setKeyParceler()`. + Additionally, the delegate also allows you to persist state of custom viewgroups that are associated with a given UI state into a Bundle. This way, you can easily create a single-Activity application using either views, fragments, or whatevers. @@ -46,7 +48,7 @@ In order to use Simple Stack, you need to add jitpack to your project root gradl and add the compile dependency to your module level gradle. - compile 'com.github.Zhuinden:simple-stack:1.0.0' + compile 'com.github.Zhuinden:simple-stack:1.1.0' ## How does it work? @@ -151,23 +153,25 @@ public class MainActivity - [Backstack](https://github.com/Zhuinden/simple-stack/blob/master/simple-stack/src/main/java/com/zhuinden/simplestack/Backstack.java): exposes operators for manipulating the backstack, and stores current history. -- [StateChanger](https://github.com/Zhuinden/simple-stack/blob/master/simple-stack/src/main/java/com/zhuinden/simplestack/StateChanger.java): interface for a class that listens to changes inside the Backstack. +- [BackstackDelegate](https://github.com/Zhuinden/simple-stack/blob/master/simple-stack/src/main/java/com/zhuinden/simplestack/BackstackDelegate.java): delegate class to hide Activity lifecycle integration, and provide view state persistence. -- [StateChange](https://github.com/Zhuinden/simple-stack/blob/master/simple-stack/src/main/java/com/zhuinden/simplestack/StateChange.java): represents a state change inside the backstack, providing previous state, new state, and the direction of the change. +- [Bundleable](https://github.com/Zhuinden/simple-stack/blob/master/simple-stack/src/main/java/com/zhuinden/simplestack/Bundleable.java): interface that allows you to persist state directly from a custom View into a Bundle, using the delegate. -- [StateChanger.Callback](https://github.com/Zhuinden/simple-stack/blob/master/simple-stack/src/main/java/com/zhuinden/simplestack/StateChange.java): the callback that signals to the backstack that the state change is complete. +- [HistoryBuilder](https://github.com/Zhuinden/simple-stack/blob/master/simple-stack/src/main/java/com/zhuinden/simplestack/HistoryBuilder.java): Convenience class for building `ArrayList`. -- [PendingStateChange](https://github.com/Zhuinden/simple-stack/blob/master/simple-stack/src/main/java/com/zhuinden/simplestack/PendingStateChange.java): represents a change that will occur when possible. +- [KeyContextWrapper](https://github.com/Zhuinden/simple-stack/blob/master/simple-stack/src/main/java/com/zhuinden/simplestack/KeyContextWrapper.java): enables the ability to use `KeyContextWrapper.getKey(context)` or `Backstack.getKey(context)` to obtain key parameter in custom viewgroup. -- [HistoryBuilder](https://github.com/Zhuinden/simple-stack/blob/master/simple-stack/src/main/java/com/zhuinden/simplestack/HistoryBuilder.java): Convenience class for building `ArrayList`. +- [KeyParceler](https://github.com/Zhuinden/simple-stack/blob/master/simple-stack/src/main/java/com/zhuinden/simplestack/KeyParceler.java): used for defining custom parcellation strategy if keys are not `Parcelable` by default. -- [SavedState](https://github.com/Zhuinden/simple-stack/blob/master/simple-stack/src/main/java/com/zhuinden/simplestack/SavedState.java): contains the key, the view state and an optional Bundle. It is used for view state persistence. +- [PendingStateChange](https://github.com/Zhuinden/simple-stack/blob/master/simple-stack/src/main/java/com/zhuinden/simplestack/PendingStateChange.java): represents a change that will occur when possible. -- [KeyContextWrapper](https://github.com/Zhuinden/simple-stack/blob/master/simple-stack/src/main/java/com/zhuinden/simplestack/KeyContextWrapper.java): enables the ability to use `KeyContextWrapper.getKey(context)` or `Backstack.getKey(context)` to obtain key parameter in custom viewgroup. +- [StateChanger](https://github.com/Zhuinden/simple-stack/blob/master/simple-stack/src/main/java/com/zhuinden/simplestack/StateChanger.java): interface for a class that listens to changes inside the Backstack. -- [BackstackDelegate](https://github.com/Zhuinden/simple-stack/blob/master/simple-stack/src/main/java/com/zhuinden/simplestack/BackstackDelegate.java): delegate class to hide Activity lifecycle integration, and provide view state persistence. +- [StateChange](https://github.com/Zhuinden/simple-stack/blob/master/simple-stack/src/main/java/com/zhuinden/simplestack/StateChange.java): represents a state change inside the backstack, providing previous state, new state, and the direction of the change. -- [Bundleable](https://github.com/Zhuinden/simple-stack/blob/master/simple-stack/src/main/java/com/zhuinden/simplestack/Bundleable.java): interface that allows you to persist state directly from a custom View into a Bundle, using the delegate. +- [StateChanger.Callback](https://github.com/Zhuinden/simple-stack/blob/master/simple-stack/src/main/java/com/zhuinden/simplestack/StateChange.java): the callback that signals to the backstack that the state change is complete. + +- [SavedState](https://github.com/Zhuinden/simple-stack/blob/master/simple-stack/src/main/java/com/zhuinden/simplestack/SavedState.java): contains the key, the view state and an optional Bundle. It is used for view state persistence. diff --git a/simple-stack-example-fragments/src/main/java/com/zhuinden/demo/DemoActivity.java b/simple-stack-example-fragments/src/main/java/com/zhuinden/demo/DemoActivity.java index 51b25771..c0901017 100644 --- a/simple-stack-example-fragments/src/main/java/com/zhuinden/demo/DemoActivity.java +++ b/simple-stack-example-fragments/src/main/java/com/zhuinden/demo/DemoActivity.java @@ -1,7 +1,6 @@ package com.zhuinden.demo; import android.os.Bundle; -import android.os.Parcelable; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; @@ -97,7 +96,7 @@ public void handleStateChange(StateChange stateChange, Callback completionCallba fragmentTransaction.setCustomAnimations(R.anim.slide_in_from_left, R.anim.slide_out_to_right); } - for(Parcelable _oldKey : stateChange.getPreviousState()) { + for(Object _oldKey : stateChange.getPreviousState()) { Key oldKey = (Key) _oldKey; Fragment fragment = getSupportFragmentManager().findFragmentByTag(oldKey.getFragmentTag()); if(fragment != null) { @@ -110,7 +109,7 @@ public void handleStateChange(StateChange stateChange, Callback completionCallba } } } - for(Parcelable _newKey : stateChange.getNewState()) { + for(Object _newKey : stateChange.getNewState()) { Key newKey = (Key) _newKey; Fragment fragment = getSupportFragmentManager().findFragmentByTag(newKey.getFragmentTag()); if(newKey.equals(stateChange.topNewState())) { diff --git a/simple-stack-example-fragments/src/main/java/com/zhuinden/simplestackdemoexamplefragments/util/FragmentStateChanger.java b/simple-stack-example-fragments/src/main/java/com/zhuinden/simplestackdemoexamplefragments/util/FragmentStateChanger.java index 3bff045f..89b3bf14 100644 --- a/simple-stack-example-fragments/src/main/java/com/zhuinden/simplestackdemoexamplefragments/util/FragmentStateChanger.java +++ b/simple-stack-example-fragments/src/main/java/com/zhuinden/simplestackdemoexamplefragments/util/FragmentStateChanger.java @@ -1,6 +1,5 @@ package com.zhuinden.simplestackdemoexamplefragments.util; -import android.os.Parcelable; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; @@ -30,7 +29,7 @@ public void handleStateChange(StateChange stateChange) { fragmentTransaction.setCustomAnimations(R.anim.slide_in_from_left, R.anim.slide_out_to_right); } - for(Parcelable _oldKey : stateChange.getPreviousState()) { + for(Object _oldKey : stateChange.getPreviousState()) { Key oldKey = (Key) _oldKey; Fragment fragment = fragmentManager.findFragmentByTag(oldKey.getFragmentTag()); if(fragment != null) { @@ -41,7 +40,7 @@ public void handleStateChange(StateChange stateChange) { } } } - for(Parcelable _newKey : stateChange.getNewState()) { + for(Object _newKey : stateChange.getNewState()) { Key newKey = (Key) _newKey; Fragment fragment = fragmentManager.findFragmentByTag(newKey.getFragmentTag()); if(newKey.equals(stateChange.topNewState())) { diff --git a/simple-stack-flow-masterdetail-fragments/src/main/java/com/example/stackmasterdetailfrag/MasterDetailFragmentStateChanger.java b/simple-stack-flow-masterdetail-fragments/src/main/java/com/example/stackmasterdetailfrag/MasterDetailFragmentStateChanger.java index 90a5ea76..c59b441e 100644 --- a/simple-stack-flow-masterdetail-fragments/src/main/java/com/example/stackmasterdetailfrag/MasterDetailFragmentStateChanger.java +++ b/simple-stack-flow-masterdetail-fragments/src/main/java/com/example/stackmasterdetailfrag/MasterDetailFragmentStateChanger.java @@ -1,6 +1,5 @@ package com.example.stackmasterdetailfrag; -import android.os.Parcelable; import android.support.annotation.NonNull; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; @@ -42,7 +41,7 @@ public void handleStateChange(StateChange stateChange) { removeFragment(fragmentTransaction, Paths.NoDetails.create()); } - for(Parcelable _previousKey : stateChange.getPreviousState()) { + for(Object _previousKey : stateChange.getPreviousState()) { Paths.Path previousKey = (Paths.Path) _previousKey; if(!stateChange.getNewState().contains(_previousKey)) { removeFragment(fragmentTransaction, previousKey); @@ -67,7 +66,7 @@ public void handleStateChange(StateChange stateChange) { } } - for(Parcelable _newKey : stateChange.getNewState()) { + for(Object _newKey : stateChange.getNewState()) { Paths.Path newKey = (Paths.Path) _newKey; if(!newKey.equals(masterKey) && !newKey.equals(detailKey)) { detachFragment(fragmentTransaction, newKey); diff --git a/simple-stack-flow-masterdetail-fragments/src/main/java/com/example/stackmasterdetailfrag/SinglePaneFragmentStateChanger.java b/simple-stack-flow-masterdetail-fragments/src/main/java/com/example/stackmasterdetailfrag/SinglePaneFragmentStateChanger.java index 2c4a3c7c..bdf2a712 100644 --- a/simple-stack-flow-masterdetail-fragments/src/main/java/com/example/stackmasterdetailfrag/SinglePaneFragmentStateChanger.java +++ b/simple-stack-flow-masterdetail-fragments/src/main/java/com/example/stackmasterdetailfrag/SinglePaneFragmentStateChanger.java @@ -1,6 +1,5 @@ package com.example.stackmasterdetailfrag; -import android.os.Parcelable; import android.support.annotation.NonNull; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; @@ -30,7 +29,7 @@ public void handleStateChange(StateChange stateChange) { fragmentTransaction.remove(noDetailsFragment); } - for(Parcelable _oldPath : stateChange.getPreviousState()) { + for(Object _oldPath : stateChange.getPreviousState()) { Paths.Path oldPath = (Paths.Path ) _oldPath; Fragment fragment = fragmentManager.findFragmentByTag(oldPath.getFragmentTag()); if(fragment != null) { @@ -42,7 +41,7 @@ public void handleStateChange(StateChange stateChange) { } } - for(Parcelable _newPath : stateChange.getNewState()) { + for(Object _newPath : stateChange.getNewState()) { Paths.Path newPath = (Paths.Path ) _newPath; Fragment fragment = fragmentManager.findFragmentByTag(newPath.getFragmentTag()); if(!newPath.equals(stateChange.topNewState())) { diff --git a/simple-stack-flow-masterdetail-fragments/src/main/java/com/example/stackmasterdetailfrag/util/MasterDetailBackstackDelegate.java b/simple-stack-flow-masterdetail-fragments/src/main/java/com/example/stackmasterdetailfrag/util/MasterDetailBackstackDelegate.java index bbcf738d..337fd4dd 100644 --- a/simple-stack-flow-masterdetail-fragments/src/main/java/com/example/stackmasterdetailfrag/util/MasterDetailBackstackDelegate.java +++ b/simple-stack-flow-masterdetail-fragments/src/main/java/com/example/stackmasterdetailfrag/util/MasterDetailBackstackDelegate.java @@ -1,6 +1,5 @@ package com.example.stackmasterdetailfrag.util; -import android.os.Parcelable; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -25,13 +24,13 @@ public MasterDetailBackstackDelegate(@Nullable StateChanger stateChanger) { } @Override - protected void clearStatesNotIn(@NonNull Map keyStateMap, @NonNull StateChange stateChange) { - Set keys = keyStateMap.keySet(); - Iterator keyIterator = keys.iterator(); + protected void clearStatesNotIn(@NonNull Map keyStateMap, @NonNull StateChange stateChange) { + Set keys = keyStateMap.keySet(); + Iterator keyIterator = keys.iterator(); while(keyIterator.hasNext()) { - Parcelable key = keyIterator.next(); + Object key = keyIterator.next(); boolean isMasterOf = false; - for(Parcelable newKey : stateChange.getNewState()) { + for(Object newKey : stateChange.getNewState()) { if(newKey instanceof Paths.MasterDetailPath) { if(key.equals(((Paths.MasterDetailPath) newKey).getMaster())) { isMasterOf = true; diff --git a/simple-stack-flow-masterdetail/src/main/java/com/example/stackmasterdetail/util/MasterDetailBackstackDelegate.java b/simple-stack-flow-masterdetail/src/main/java/com/example/stackmasterdetail/util/MasterDetailBackstackDelegate.java index 7831bdf6..4296e1de 100644 --- a/simple-stack-flow-masterdetail/src/main/java/com/example/stackmasterdetail/util/MasterDetailBackstackDelegate.java +++ b/simple-stack-flow-masterdetail/src/main/java/com/example/stackmasterdetail/util/MasterDetailBackstackDelegate.java @@ -1,6 +1,5 @@ package com.example.stackmasterdetail.util; -import android.os.Parcelable; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -25,13 +24,13 @@ public MasterDetailBackstackDelegate(@Nullable StateChanger stateChanger) { } @Override - protected void clearStatesNotIn(@NonNull Map keyStateMap, @NonNull StateChange stateChange) { - Set keys = keyStateMap.keySet(); - Iterator keyIterator = keys.iterator(); + protected void clearStatesNotIn(@NonNull Map keyStateMap, @NonNull StateChange stateChange) { + Set keys = keyStateMap.keySet(); + Iterator keyIterator = keys.iterator(); while(keyIterator.hasNext()) { - Parcelable key = keyIterator.next(); + Object key = keyIterator.next(); boolean isMasterOf = false; - for(Parcelable newKey : stateChange.getNewState()) { + for(Object newKey : stateChange.getNewState()) { if(newKey instanceof Paths.MasterDetailPath) { if(key.equals(((Paths.MasterDetailPath) newKey).getMaster())) { isMasterOf = true; diff --git a/simple-stack/src/main/java/com/zhuinden/simplestack/Backstack.java b/simple-stack/src/main/java/com/zhuinden/simplestack/Backstack.java index 754dbf71..847d9cc6 100644 --- a/simple-stack/src/main/java/com/zhuinden/simplestack/Backstack.java +++ b/simple-stack/src/main/java/com/zhuinden/simplestack/Backstack.java @@ -16,7 +16,6 @@ package com.zhuinden.simplestack; import android.content.Context; -import android.os.Parcelable; import android.support.annotation.IntDef; import android.support.annotation.NonNull; @@ -30,14 +29,14 @@ import static java.lang.annotation.RetentionPolicy.SOURCE; /** - * The {@link Backstack} holds the current state, in the form of a list of Parcelables. + * The {@link Backstack} holds the current state, in the form of a list of Objects. * It queues up {@link StateChange}s while a {@link StateChanger} is not available. * When a {@link StateChanger} is available, it attempts to execute the queued {@link StateChange}s. - * A {@link StateChanger} can be either set to initialize, or to reattach. - * Initialize begins an initializing {@link StateChange} to set up initial state, reattach does not. + * A {@link StateChanger} can be either set to {@link Backstack#INITIALIZE}, or to {@link Backstack#REATTACH}. + * {@link Backstack#INITIALIZE} begins an initializing {@link StateChange} to set up initial state, {@link Backstack#REATTACH} does not. */ public class Backstack { - public static T getKey(Context context) { + public static T getKey(Context context) { return KeyContextWrapper.getKey(context); } @@ -51,10 +50,10 @@ public static T getKey(Context context) { public static final int REATTACH = 1; // - private final List originalStack = new ArrayList<>(); + private final List originalStack = new ArrayList<>(); - private final List initialParameters; - private List stack = originalStack; + private final List initialParameters; + private List stack = originalStack; private LinkedList queuedStateChanges = new LinkedList<>(); @@ -65,7 +64,7 @@ public static T getKey(Context context) { * * @param initialKeys */ - public Backstack(@NonNull Parcelable... initialKeys) { + public Backstack(@NonNull Object... initialKeys) { if(initialKeys == null || initialKeys.length <= 0) { throw new IllegalArgumentException("At least one initial key must be defined"); } @@ -77,7 +76,7 @@ public Backstack(@NonNull Parcelable... initialKeys) { * * @param initialKeys */ - public Backstack(@NonNull List initialKeys) { + public Backstack(@NonNull List initialKeys) { if(initialKeys == null) { throw new NullPointerException("Initial key list should not be null"); } @@ -109,7 +108,7 @@ public void setStateChanger(@NonNull StateChanger stateChanger, @StateChangerReg this.stateChanger = stateChanger; if(registerMode == INITIALIZE && (queuedStateChanges.size() <= 1 || stack.isEmpty())) { if(!beginStateChangeIfPossible()) { - ArrayList newHistory = new ArrayList<>(); + ArrayList newHistory = new ArrayList<>(); newHistory.addAll(selectActiveHistory()); stack = initialParameters; enqueueStateChange(newHistory, StateChange.REPLACE, true); @@ -133,12 +132,12 @@ public void removeStateChanger() { * * @param newKey the target state. */ - public void goTo(@NonNull Parcelable newKey) { + public void goTo(@NonNull Object newKey) { checkNewKey(newKey); - ArrayList newHistory = new ArrayList<>(); + ArrayList newHistory = new ArrayList<>(); boolean isNewKey = true; - for(Parcelable key : selectActiveHistory()) { + for(Object key : selectActiveHistory()) { newHistory.add(key); if(key.equals(newKey)) { isNewKey = false; @@ -170,9 +169,9 @@ public boolean goBack() { stack.clear(); return false; } - ArrayList newHistory = new ArrayList<>(); + ArrayList newHistory = new ArrayList<>(); - List activeHistory = selectActiveHistory(); + List activeHistory = selectActiveHistory(); for(int i = 0; i < activeHistory.size() - 1; i++) { newHistory.add(activeHistory.get(i)); } @@ -186,7 +185,7 @@ public boolean goBack() { * @param newHistory the new active history. * @param direction The direction of the state change: BACKWARD, FORWARD or REPLACE. */ - public void setHistory(@NonNull List newHistory, @StateChange.StateChangeDirection int direction) { + public void setHistory(@NonNull List newHistory, @StateChange.StateChangeDirection int direction) { checkNewHistory(newHistory); enqueueStateChange(newHistory, direction, false); } @@ -196,8 +195,8 @@ public void setHistory(@NonNull List newHistory, @StateChange.StateC * * @return the unmodifiable copy of history. */ - public List getHistory() { - List copy = new ArrayList<>(); + public List getHistory() { + List copy = new ArrayList<>(); copy.addAll(stack); return Collections.unmodifiableList(copy); } @@ -211,13 +210,13 @@ public boolean isStateChangePending() { return !queuedStateChanges.isEmpty(); } - private void enqueueStateChange(List newHistory, int direction, boolean initialization) { + private void enqueueStateChange(List newHistory, int direction, boolean initialization) { PendingStateChange pendingStateChange = new PendingStateChange(newHistory, direction, initialization); queuedStateChanges.add(pendingStateChange); beginStateChangeIfPossible(); } - private List selectActiveHistory() { + private List selectActiveHistory() { if(stack.isEmpty() && queuedStateChanges.size() <= 0) { return initialParameters; } else if(queuedStateChanges.size() <= 0) { @@ -241,10 +240,10 @@ private boolean beginStateChangeIfPossible() { private void changeState(final PendingStateChange pendingStateChange) { boolean initialization = pendingStateChange.initialization; - List newHistory = pendingStateChange.newHistory; + List newHistory = pendingStateChange.newHistory; @StateChange.StateChangeDirection int direction = pendingStateChange.direction; - List previousState; + List previousState; if(initialization) { previousState = Collections.emptyList(); } else { @@ -347,13 +346,13 @@ public void executePendingStateChange() { } // argument checks - private void checkNewHistory(List newHistory) { + private void checkNewHistory(List newHistory) { if(newHistory == null || newHistory.isEmpty()) { throw new IllegalArgumentException("New history cannot be null or empty"); } } - private void checkNewKey(Parcelable newKey) { + private void checkNewKey(Object newKey) { if(newKey == null) { throw new IllegalArgumentException("Key cannot be null"); } diff --git a/simple-stack/src/main/java/com/zhuinden/simplestack/BackstackDelegate.java b/simple-stack/src/main/java/com/zhuinden/simplestack/BackstackDelegate.java index c2592000..5fedf62a 100644 --- a/simple-stack/src/main/java/com/zhuinden/simplestack/BackstackDelegate.java +++ b/simple-stack/src/main/java/com/zhuinden/simplestack/BackstackDelegate.java @@ -16,6 +16,7 @@ package com.zhuinden.simplestack; import android.os.Bundle; +import android.os.Parcel; import android.os.Parcelable; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -34,6 +35,56 @@ * This should be used in Activities to make sure that the {@link Backstack} survives both configuration changes and process death. */ public class BackstackDelegate { + private static class ParcelledState + implements Parcelable { + Parcelable parcelableKey; + SparseArray viewHierarchyState; + Bundle bundle; + + private ParcelledState() { + } + + protected ParcelledState(Parcel in) { + parcelableKey = in.readParcelable(getClass().getClassLoader()); + // noinspection unchecked + viewHierarchyState = in.readSparseArray(getClass().getClassLoader()); + boolean hasBundle = in.readByte() > 0; + if(hasBundle) { + bundle = in.readBundle(getClass().getClassLoader()); + } + } + + public static final Creator CREATOR = new Creator() { + @Override + public ParcelledState createFromParcel(Parcel in) { + return new ParcelledState(in); + } + + @Override + public ParcelledState[] newArray(int size) { + return new ParcelledState[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeParcelable(parcelableKey, flags); + // noinspection unchecked + SparseArray sparseArray = (SparseArray) viewHierarchyState; + dest.writeSparseArray(sparseArray); + dest.writeByte(bundle != null ? (byte) 0x01 : 0x00); + if(bundle != null) { + dest.writeBundle(bundle); + } + } + + } + private final Backstack.CompletionListener completionListener = new Backstack.CompletionListener() { @Override public void stateChangeCompleted(@NonNull StateChange stateChange) { @@ -44,6 +95,35 @@ public void stateChangeCompleted(@NonNull StateChange stateChange) { private static final String UNINITIALIZED = ""; private String persistenceTag = UNINITIALIZED; + private KeyParceler keyParceler = new KeyParceler() { + @Override + public Parcelable toParcelable(Object object) { + return (Parcelable) object; + } + + @Override + public Object fromParcelable(Parcelable parcelable) { + return parcelable; + } + }; + + /** + * Specifies a custom {@link KeyParceler}, allowing key parcellation strategies to be used for turning a key into Parcelable. + * + * If used, this method must be called before {@link BackstackDelegate#onCreate(Bundle, Object, ArrayList)}. + * + * @param keyParceler The custom {@link KeyParceler}. + */ + public void setKeyParceler(KeyParceler keyParceler) { + if(backstack != null) { + throw new IllegalStateException("Custom key parceler should be set before calling `onCreate()`"); + } + if(keyParceler == null) { + throw new IllegalArgumentException("The key parceler cannot be null!"); + } + this.keyParceler = keyParceler; + } + private static final String HISTORY = "simplestack.HISTORY"; private static final String STATES = HISTORY + "_STATES"; @@ -80,7 +160,7 @@ private String getStateTag() { Backstack backstack; - Map keyStateMap = new HashMap<>(); + Map keyStateMap = new HashMap<>(); StateChanger stateChanger; @@ -106,17 +186,28 @@ public BackstackDelegate(@Nullable StateChanger stateChanger) { * @param nonConfigurationInstance The {@link NonConfigurationInstance} that is typically obtained with getLastCustomNonConfigurationInstance(). * @param initialKeys A list of the keys that are used to set as initial history of the backstack. */ - public void onCreate(@Nullable Bundle savedInstanceState, @Nullable Object nonConfigurationInstance, @NonNull ArrayList initialKeys) { + public void onCreate(@Nullable Bundle savedInstanceState, @Nullable Object nonConfigurationInstance, @NonNull ArrayList initialKeys) { if(nonConfigurationInstance != null && !(nonConfigurationInstance instanceof NonConfigurationInstance)) { throw new IllegalArgumentException( "The provided non configuration instance must be of type BackstackDelegate.NonConfigurationInstance!"); } - ArrayList keys; + ArrayList keys; if(savedInstanceState != null) { - keys = savedInstanceState.getParcelableArrayList(getHistoryTag()); - List savedStates = savedInstanceState.getParcelableArrayList(getStateTag()); + List parcelledKeys = savedInstanceState.getParcelableArrayList(getHistoryTag()); + keys = new ArrayList<>(); + if(parcelledKeys != null) { + for(Parcelable parcelledKey : parcelledKeys) { + keys.add(keyParceler.fromParcelable(parcelledKey)); + } + } + List savedStates = savedInstanceState.getParcelableArrayList(getStateTag()); if(savedStates != null) { - for(SavedState savedState : savedStates) { + for(ParcelledState parcelledState : savedStates) { + SavedState savedState = SavedState.builder() + .setKey(keyParceler.fromParcelable(parcelledState.parcelableKey)) + .setViewHierarchyState(parcelledState.viewHierarchyState) + .setBundle(parcelledState.bundle) + .build(); keyStateMap.put(savedState.getKey(), savedState); } } @@ -189,8 +280,21 @@ public boolean onBackPressed() { * @param outState the Bundle into which the backstack history and view states are saved. */ public void onSaveInstanceState(@NonNull Bundle outState) { - outState.putParcelableArrayList(getHistoryTag(), HistoryBuilder.from(backstack).build()); - outState.putParcelableArrayList(getStateTag(), new ArrayList<>(keyStateMap.values())); + ArrayList history = new ArrayList<>(); + for(Object key : backstack.getHistory()) { + history.add(keyParceler.toParcelable(key)); + } + outState.putParcelableArrayList(getHistoryTag(), history); + + ArrayList states = new ArrayList<>(); + for(SavedState savedState : keyStateMap.values()) { + ParcelledState parcelledState = new ParcelledState(); + parcelledState.parcelableKey = keyParceler.toParcelable(savedState.getKey()); + parcelledState.viewHierarchyState = savedState.getViewHierarchyState(); + parcelledState.bundle = savedState.getBundle(); + states.add(parcelledState); + } + outState.putParcelableArrayList(getStateTag(), states); } /** @@ -251,7 +355,7 @@ public Backstack getBackstack() { */ public void persistViewToState(@Nullable View view) { if(view != null) { - Parcelable key = KeyContextWrapper.getKey(view.getContext()); + Object key = KeyContextWrapper.getKey(view.getContext()); if(key == null) { throw new IllegalArgumentException("The view [" + view + "] contained no key!"); } @@ -279,7 +383,7 @@ public void restoreViewFromState(@NonNull View view) { if(view == null) { throw new IllegalArgumentException("You cannot restore state into null view!"); } - Parcelable newKey = KeyContextWrapper.getKey(view.getContext()); + Object newKey = KeyContextWrapper.getKey(view.getContext()); SavedState savedState = getSavedState(newKey); view.restoreHierarchyState(savedState.getViewHierarchyState()); if(view instanceof Bundleable) { @@ -295,7 +399,7 @@ public void restoreViewFromState(@NonNull View view) { * @return the saved state that belongs to the given key. */ @NonNull - public SavedState getSavedState(@NonNull Parcelable key) { + public SavedState getSavedState(@NonNull Object key) { if(key == null) { throw new IllegalArgumentException("Key cannot be null!"); } @@ -311,7 +415,7 @@ protected void stateChangeCompleted(StateChange stateChange) { } } - protected void clearStatesNotIn(@NonNull Map keyStateMap, @NonNull StateChange stateChange) { + protected void clearStatesNotIn(@NonNull Map keyStateMap, @NonNull StateChange stateChange) { keyStateMap.keySet().retainAll(stateChange.getNewState()); } diff --git a/simple-stack/src/main/java/com/zhuinden/simplestack/HistoryBuilder.java b/simple-stack/src/main/java/com/zhuinden/simplestack/HistoryBuilder.java index da0df96b..229618fb 100644 --- a/simple-stack/src/main/java/com/zhuinden/simplestack/HistoryBuilder.java +++ b/simple-stack/src/main/java/com/zhuinden/simplestack/HistoryBuilder.java @@ -15,7 +15,6 @@ */ package com.zhuinden.simplestack; -import android.os.Parcelable; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -25,11 +24,11 @@ import java.util.List; /** - * Convenience class for creating ArrayList of Parcelables, for backstack history. + * Convenience class for creating ArrayList of Objects, for backstack history. */ public class HistoryBuilder - implements Iterable { - private ArrayList list = new ArrayList<>(); + implements Iterable { + private ArrayList list = new ArrayList<>(); private HistoryBuilder() { // use newBuilder() } @@ -66,7 +65,7 @@ public static HistoryBuilder from(@NonNull BackstackDelegate backstackDelegate) * @param keys * @return the newly created {@link HistoryBuilder}. */ - public static HistoryBuilder from(@NonNull List keys) { + public static HistoryBuilder from(@NonNull List keys) { return newBuilder().addAll(keys); } @@ -80,12 +79,12 @@ public static HistoryBuilder newBuilder() { } /** - * Creates a new array list of parcelable that contains only the provided key. + * Creates a new array list of Object that contains only the provided key. * * @param key - * @return an array list of parcelable that contains the key. + * @return an array list of Object that contains the key. */ - public static ArrayList single(@NonNull Parcelable key) { + public static ArrayList single(@NonNull Object key) { return newBuilder() .add(key) .build(); @@ -97,7 +96,7 @@ public static ArrayList single(@NonNull Parcelable key) { * @param keys * @return the current builder. */ - public HistoryBuilder addAll(@NonNull List keys) { + public HistoryBuilder addAll(@NonNull List keys) { if(keys == null) { throw new IllegalArgumentException("Provided collection cannot be null"); } @@ -112,7 +111,7 @@ public HistoryBuilder addAll(@NonNull List keys) { * @param index * @return the current builder. */ - public HistoryBuilder addAllAt(@NonNull List keys, int index) { + public HistoryBuilder addAllAt(@NonNull List keys, int index) { if(keys == null) { throw new IllegalArgumentException("Provided collection cannot be null"); } @@ -136,7 +135,7 @@ public HistoryBuilder clear() { * @param key * @return true if the builder contains the given key. */ - public boolean contains(@NonNull Parcelable key) { + public boolean contains(@NonNull Object key) { checkKey(key); return list.contains(key); } @@ -147,7 +146,7 @@ public boolean contains(@NonNull Parcelable key) { * @param keys * @return true if the builder contains all keys. */ - public boolean containsAll(@NonNull Collection keys) { + public boolean containsAll(@NonNull Collection keys) { if(keys == null) { throw new IllegalArgumentException("Keys cannot be null!"); } @@ -169,7 +168,7 @@ public int size() { * @param key * @return the current builder. */ - public HistoryBuilder remove(@NonNull Parcelable key) { + public HistoryBuilder remove(@NonNull Object key) { checkKey(key); list.remove(key); return this; @@ -192,7 +191,7 @@ public HistoryBuilder removeAt(int index) { * @param keys * @return the current builder. */ - public HistoryBuilder retainAll(@NonNull Collection keys) { + public HistoryBuilder retainAll(@NonNull Collection keys) { checkKeys(keys); list.retainAll(keys); return this; @@ -228,7 +227,7 @@ public HistoryBuilder removeLast() { * @param key * @return the current builder. */ - public HistoryBuilder removeUntil(@NonNull Parcelable key) { + public HistoryBuilder removeUntil(@NonNull Object key) { checkKey(key); while(!list.isEmpty() && !getLast().equals(key)) { removeLast(); @@ -245,7 +244,7 @@ public HistoryBuilder removeUntil(@NonNull Parcelable key) { * @param key * @return the index, -1 if not found. */ - public int indexOf(@NonNull Parcelable key) { + public int indexOf(@NonNull Object key) { checkKey(key); return list.indexOf(key); } @@ -256,7 +255,7 @@ public int indexOf(@NonNull Parcelable key) { * @param index * @return the key at the given index */ - public T get(int index) { + public T get(int index) { // noinspection unchecked return (T) list.get(index); } @@ -268,7 +267,7 @@ public T get(int index) { * @return the key at the last index */ @Nullable - public T getLast() { + public T getLast() { // noinspection unchecked return (T)(list.isEmpty() ? null : list.get(list.size() - 1)); } @@ -279,7 +278,7 @@ public T getLast() { * @param key * @return the current builder. */ - public HistoryBuilder add(@NonNull Parcelable key) { + public HistoryBuilder add(@NonNull Object key) { checkKey(key); list.add(key); return this; @@ -292,7 +291,7 @@ public HistoryBuilder add(@NonNull Parcelable key) { * @param index * @return the current builder. */ - public HistoryBuilder add(@NonNull Parcelable key, int index) { + public HistoryBuilder add(@NonNull Object key, int index) { checkKey(key); list.add(index, key); return this; @@ -304,7 +303,7 @@ public HistoryBuilder add(@NonNull Parcelable key, int index) { * @return the iterator */ @Override - public Iterator iterator() { + public Iterator iterator() { return list.iterator(); } @@ -313,18 +312,18 @@ public Iterator iterator() { * * @return the built history. */ - public ArrayList build() { + public ArrayList build() { return new ArrayList<>(this.list); } // validations - private void checkKey(Parcelable key) { + private void checkKey(Object key) { if(key == null) { throw new IllegalArgumentException("History key cannot be null!"); } } - private void checkKeys(Collection keys) { + private void checkKeys(Collection keys) { if(keys == null) { throw new IllegalArgumentException("Keys cannot be null!"); } diff --git a/simple-stack/src/main/java/com/zhuinden/simplestack/KeyContextWrapper.java b/simple-stack/src/main/java/com/zhuinden/simplestack/KeyContextWrapper.java index 35268cae..56b0a3af 100644 --- a/simple-stack/src/main/java/com/zhuinden/simplestack/KeyContextWrapper.java +++ b/simple-stack/src/main/java/com/zhuinden/simplestack/KeyContextWrapper.java @@ -17,7 +17,6 @@ import android.content.Context; import android.content.ContextWrapper; -import android.os.Parcelable; import android.support.annotation.NonNull; import android.view.LayoutInflater; @@ -31,9 +30,9 @@ public class KeyContextWrapper LayoutInflater layoutInflater; - final Parcelable key; + final Object key; - public KeyContextWrapper(Context base, @NonNull Parcelable key) { + public KeyContextWrapper(Context base, @NonNull Object key) { super(base); if(key == null) { throw new IllegalArgumentException("Key cannot be null!"); @@ -60,7 +59,7 @@ public Object getSystemService(String name) { * @param context the key context wrapper in which the key can be found. * @return the key. */ - public static T getKey(Context context) { + public static T getKey(Context context) { // noinspection ResourceType Object key = context.getSystemService(TAG); // noinspection unchecked diff --git a/simple-stack/src/main/java/com/zhuinden/simplestack/KeyParceler.java b/simple-stack/src/main/java/com/zhuinden/simplestack/KeyParceler.java new file mode 100644 index 00000000..1b44d28a --- /dev/null +++ b/simple-stack/src/main/java/com/zhuinden/simplestack/KeyParceler.java @@ -0,0 +1,24 @@ +package com.zhuinden.simplestack; + +import android.os.Parcelable; + +/** + * An interface to allow using any key in the backstack, as long as it is possible to persist and restore it as a Parcelable. + */ +public interface KeyParceler { + /** + * Transforms the input parameter into a Parcelable. + * + * @param object The key that is to be transformed into a Parcelable. + * @return the Parcelable the key is transformed into. + */ + Parcelable toParcelable(Object object); + + /** + * Creates the original key based on the input Parcelable. + * + * @param parcelable the Parcelable the key was transformed into. + * @return The key that was transformed into a Parcelable. + */ + Object fromParcelable(Parcelable parcelable); +} diff --git a/simple-stack/src/main/java/com/zhuinden/simplestack/PendingStateChange.java b/simple-stack/src/main/java/com/zhuinden/simplestack/PendingStateChange.java index b64993e3..f0866622 100644 --- a/simple-stack/src/main/java/com/zhuinden/simplestack/PendingStateChange.java +++ b/simple-stack/src/main/java/com/zhuinden/simplestack/PendingStateChange.java @@ -15,8 +15,6 @@ */ package com.zhuinden.simplestack; -import android.os.Parcelable; - import java.util.List; /** @@ -29,7 +27,7 @@ enum Status { COMPLETED } - final List newHistory; + final List newHistory; final int direction; final boolean initialization; @@ -38,7 +36,7 @@ enum Status { StateChanger.Callback completionCallback; boolean didForceExecute = false; - PendingStateChange(List newHistory, @StateChange.StateChangeDirection int direction, boolean initialization) { + PendingStateChange(List newHistory, @StateChange.StateChangeDirection int direction, boolean initialization) { this.newHistory = newHistory; this.direction = direction; this.initialization = initialization; diff --git a/simple-stack/src/main/java/com/zhuinden/simplestack/SavedState.java b/simple-stack/src/main/java/com/zhuinden/simplestack/SavedState.java index 9260abae..7cc5b250 100644 --- a/simple-stack/src/main/java/com/zhuinden/simplestack/SavedState.java +++ b/simple-stack/src/main/java/com/zhuinden/simplestack/SavedState.java @@ -16,7 +16,6 @@ package com.zhuinden.simplestack; import android.os.Bundle; -import android.os.Parcel; import android.os.Parcelable; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -28,16 +27,15 @@ * * A {@link SavedState} represents the state of the view that is bound to a given key. */ -public class SavedState - implements Parcelable { - private Parcelable key; +public class SavedState { + private Object key; private SparseArray viewHierarchyState; private Bundle bundle; private SavedState() { } - public Parcelable getKey() { + public Object getKey() { return key; } @@ -67,14 +65,14 @@ public static Builder builder() { * Keys are not optional. */ public static class Builder { - private Parcelable key; + private Object key; private SparseArray viewHierarchyState = new SparseArray<>(); private Bundle bundle; Builder() { } - public Builder setKey(@NonNull Parcelable key) { + public Builder setKey(@NonNull Object key) { if(key == null) { throw new IllegalArgumentException("Key cannot be null"); } @@ -107,45 +105,6 @@ public SavedState build() { } } - protected SavedState(Parcel in) { - key = in.readParcelable(getClass().getClassLoader()); - // noinspection unchecked - viewHierarchyState = in.readSparseArray(getClass().getClassLoader()); - boolean hasBundle = in.readByte() > 0; - if(hasBundle) { - bundle = in.readBundle(getClass().getClassLoader()); - } - } - - public static final Creator CREATOR = new Creator() { - @Override - public SavedState createFromParcel(Parcel in) { - return new SavedState(in); - } - - @Override - public SavedState[] newArray(int size) { - return new SavedState[size]; - } - }; - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeParcelable(key, flags); - // noinspection unchecked - SparseArray sparseArray = (SparseArray)viewHierarchyState; - dest.writeSparseArray(sparseArray); - dest.writeByte(bundle != null ? (byte)0x01 : 0x00); - if(bundle != null) { - dest.writeBundle(bundle); - } - } - @Override public boolean equals(Object obj) { if(obj == null) { diff --git a/simple-stack/src/main/java/com/zhuinden/simplestack/StateChange.java b/simple-stack/src/main/java/com/zhuinden/simplestack/StateChange.java index 5f105470..7530b04b 100644 --- a/simple-stack/src/main/java/com/zhuinden/simplestack/StateChange.java +++ b/simple-stack/src/main/java/com/zhuinden/simplestack/StateChange.java @@ -16,7 +16,6 @@ package com.zhuinden.simplestack; import android.content.Context; -import android.os.Parcelable; import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -39,14 +38,14 @@ public class StateChange { public static final int BACKWARD = -1; public static final int FORWARD = 1; - StateChange(List previousState, List newState, @StateChangeDirection int direction) { + StateChange(List previousState, List newState, @StateChangeDirection int direction) { this.previousState = previousState; this.newState = newState; this.direction = direction; } - List previousState; - List newState; + List previousState; + List newState; int direction; /** @@ -56,7 +55,7 @@ public class StateChange { * @return the previous state. */ @NonNull - public List getPreviousState() { + public List getPreviousState() { return previousState; } @@ -66,7 +65,7 @@ public List getPreviousState() { * @return the new state. */ @NonNull - public List getNewState() { + public List getNewState() { return newState; } @@ -86,7 +85,7 @@ public int getDirection() { * @return the last element in previous state, or null if empty. */ @Nullable - public T topPreviousState() { + public T topPreviousState() { if(previousState.size() > 0) { // noinspection unchecked return (T) previousState.get(previousState.size() - 1); @@ -101,7 +100,7 @@ public T topPreviousState() { * @return the last element in new state. */ @NonNull - public T topNewState() { + public T topNewState() { // noinspection unchecked return (T) newState.get(newState.size() - 1); } @@ -114,7 +113,7 @@ public T topNewState() { * @return the context to use used with LayoutInflater.from(). */ @NonNull - public Context createContext(Context base, Parcelable key) { + public Context createContext(Context base, Object key) { return new KeyContextWrapper(base, key); } } diff --git a/simple-stack/src/test/java/com/zhuinden/simplestack/BackstackDelegateTest.java b/simple-stack/src/test/java/com/zhuinden/simplestack/BackstackDelegateTest.java index 44601822..79b6019e 100644 --- a/simple-stack/src/test/java/com/zhuinden/simplestack/BackstackDelegateTest.java +++ b/simple-stack/src/test/java/com/zhuinden/simplestack/BackstackDelegateTest.java @@ -15,8 +15,6 @@ */ package com.zhuinden.simplestack; -import android.os.Parcelable; - import org.junit.Test; import java.util.ArrayList; @@ -64,7 +62,7 @@ public void setTwoDifferentPersistenceTagsShouldThrow() { @Test public void setPersistenceTagAfterOnCreateShouldThrow() { BackstackDelegate backstackDelegate = new BackstackDelegate(null); - backstackDelegate.onCreate(null, null, new ArrayList() {{ + backstackDelegate.onCreate(null, null, new ArrayList() {{ add(new TestKey("hello")); }}); try { diff --git a/simple-stack/src/test/java/com/zhuinden/simplestack/FlowTest.java b/simple-stack/src/test/java/com/zhuinden/simplestack/FlowTest.java index c7c62f55..a97c2c52 100644 --- a/simple-stack/src/test/java/com/zhuinden/simplestack/FlowTest.java +++ b/simple-stack/src/test/java/com/zhuinden/simplestack/FlowTest.java @@ -126,7 +126,7 @@ public void writeToParcel(Parcel dest, int flags) { final TestKey charlie = new TestKey("Charlie"); final TestKey delta = new TestKey("Delta"); - List lastStack; + List lastStack; int lastDirection; class FlowDispatcher @@ -146,7 +146,7 @@ public void setUp() { @Test public void oneTwoThree() { - List history = HistoryBuilder.single(new Uno()); + List history = HistoryBuilder.single(new Uno()); Backstack flow = new Backstack(history); flow.setStateChanger(new FlowDispatcher(), Backstack.INITIALIZE); @@ -171,7 +171,7 @@ public void oneTwoThree() { @Test public void historyChangesAfterListenerCall() { - final List firstHistory = HistoryBuilder.single(new Uno()); + final List firstHistory = HistoryBuilder.single(new Uno()); class Ourrobouros implements StateChanger { @@ -184,7 +184,7 @@ class Ourrobouros @Override public void handleStateChange(@NonNull StateChange stateChange, @NonNull StateChanger.Callback onComplete) { assertThat(firstHistory).hasSameSizeAs(flow.getHistory()); - Iterator original = firstHistory.iterator(); + Iterator original = firstHistory.iterator(); for(Object o : flow.getHistory()) { assertThat(o).isEqualTo(original.next()); } @@ -198,7 +198,7 @@ public void handleStateChange(@NonNull StateChange stateChange, @NonNull StateCh @Test public void historyPushAllIsPushy() { - List history = HistoryBuilder.from(Arrays.asList(able, baker, charlie)).build(); + List history = HistoryBuilder.from(Arrays.asList(able, baker, charlie)).build(); assertThat(history.size()).isEqualTo(3); Backstack flow = new Backstack(history); @@ -215,12 +215,12 @@ public void historyPushAllIsPushy() { @Test public void setHistoryWorks() { - List history = HistoryBuilder.from(Arrays.asList(able, baker)).build(); + List history = HistoryBuilder.from(Arrays.asList(able, baker)).build(); Backstack flow = new Backstack(history); FlowDispatcher handleStateChangeer = new FlowDispatcher(); flow.setStateChanger(handleStateChangeer, Backstack.INITIALIZE); - List newHistory = HistoryBuilder.from(Arrays.asList(charlie, delta)).build(); + List newHistory = HistoryBuilder.from(Arrays.asList(charlie, delta)).build(); flow.setHistory(newHistory, StateChange.FORWARD); assertThat(lastDirection).isSameAs(StateChange.FORWARD); assertThat(lastStack.get(lastStack.size() - 1)).isSameAs(delta); @@ -231,7 +231,7 @@ public void setHistoryWorks() { @Test public void setObjectGoesBack() { - List history = HistoryBuilder.from(Arrays.asList(able, baker, charlie, delta)).build(); + List history = HistoryBuilder.from(Arrays.asList(able, baker, charlie, delta)).build(); Backstack flow = new Backstack(history); flow.setStateChanger(new FlowDispatcher(), Backstack.INITIALIZE); @@ -255,7 +255,7 @@ public void setObjectGoesBack() { @Test public void setObjectToMissingObjectPushes() { - List history = HistoryBuilder.from(Arrays.asList(able, baker)).build(); + List history = HistoryBuilder.from(Arrays.asList(able, baker)).build(); Backstack flow = new Backstack(history); flow.setStateChanger(new FlowDispatcher(), Backstack.INITIALIZE); assertThat(history.size()).isEqualTo(2); @@ -277,7 +277,7 @@ public void setObjectToMissingObjectPushes() { @Test public void setObjectKeepsOriginal() { - List history = HistoryBuilder.from(Arrays.asList(able, baker)).build(); + List history = HistoryBuilder.from(Arrays.asList(able, baker)).build(); Backstack flow = new Backstack(history); flow.setStateChanger(new FlowDispatcher(), Backstack.INITIALIZE); assertThat(history.size()).isEqualTo(2); @@ -292,7 +292,7 @@ public void setObjectKeepsOriginal() { @Test public void replaceHistoryResultsInLengthOneHistory() { - List history = HistoryBuilder.from(Arrays.asList(able, baker, charlie)).build(); + List history = HistoryBuilder.from(Arrays.asList(able, baker, charlie)).build(); Backstack flow = new Backstack(history); flow.setStateChanger(new FlowDispatcher(), Backstack.INITIALIZE); assertThat(history.size()).isEqualTo(3); @@ -307,7 +307,7 @@ public void replaceHistoryResultsInLengthOneHistory() { @Test public void replaceTopDoesNotAlterHistoryLength() { - List history = HistoryBuilder.from(Arrays.asList(able, baker, charlie)).build(); + List history = HistoryBuilder.from(Arrays.asList(able, baker, charlie)).build(); Backstack flow = new Backstack(history); flow.setStateChanger(new FlowDispatcher(), Backstack.INITIALIZE); assertThat(history.size()).isEqualTo(3); @@ -327,14 +327,14 @@ public void setHistoryKeepsOriginals() { TestKey baker = new TestKey("Baker"); TestKey charlie = new TestKey("Charlie"); TestKey delta = new TestKey("Delta"); - List history = HistoryBuilder.from(Arrays.asList(able, baker, charlie, delta)).build(); + List history = HistoryBuilder.from(Arrays.asList(able, baker, charlie, delta)).build(); Backstack flow = new Backstack(history); flow.setStateChanger(new FlowDispatcher(), Backstack.INITIALIZE); assertThat(history.size()).isEqualTo(4); TestKey echo = new TestKey("Echo"); TestKey foxtrot = new TestKey("Foxtrot"); - List newHistory = HistoryBuilder.from(Arrays.asList(able, baker, echo, foxtrot)).build(); + List newHistory = HistoryBuilder.from(Arrays.asList(able, baker, echo, foxtrot)).build(); flow.setHistory(newHistory, StateChange.REPLACE); assertThat(lastStack.size()).isEqualTo(4); assertThat(lastStack.get(lastStack.size() - 1)).isEqualTo(foxtrot); @@ -404,7 +404,7 @@ public void writeToParcel(Parcel dest, int flags) { @Test public void setCallsEquals() { - List history = HistoryBuilder.newBuilder() + List history = HistoryBuilder.newBuilder() .addAll(Arrays.asList(new Picky("Able"), new Picky("Baker"), new Picky("Charlie"), new Picky("Delta"))) .build(); Backstack flow = new Backstack(history); diff --git a/simple-stack/src/test/java/com/zhuinden/simplestack/HistoryBuilderTest.java b/simple-stack/src/test/java/com/zhuinden/simplestack/HistoryBuilderTest.java index 7cb1500f..d400d5cf 100644 --- a/simple-stack/src/test/java/com/zhuinden/simplestack/HistoryBuilderTest.java +++ b/simple-stack/src/test/java/com/zhuinden/simplestack/HistoryBuilderTest.java @@ -16,8 +16,6 @@ package com.zhuinden.simplestack; -import android.os.Parcelable; - import org.junit.Assert; import org.junit.Test; @@ -57,7 +55,7 @@ public void removeUntilRemovesUntil() { TestKey hi = new TestKey("hi"); TestKey hello = new TestKey("hello"); TestKey bye = new TestKey("bye"); - ArrayList history = HistoryBuilder.newBuilder().add(hi).add(hello).add(bye).removeUntil(hi).build(); + ArrayList history = HistoryBuilder.newBuilder().add(hi).add(hello).add(bye).removeUntil(hi).build(); assertThat(history).containsExactly(hi); } @@ -81,7 +79,7 @@ public void removeLastRemovesLast() { TestKey hello = new TestKey("hello"); TestKey bye = new TestKey("bye"); HistoryBuilder builder = HistoryBuilder.newBuilder().add(hi).add(hello).add(bye); - List history = builder.removeLast().build(); + List history = builder.removeLast().build(); assertThat(history).containsExactly(hi, hello); } @@ -109,7 +107,7 @@ public void keyCannotBeNull() { public void historyBuilderWorksAsIterable() { HistoryBuilder historyBuilder = HistoryBuilder.newBuilder().add(new TestKey("hello")).add(new TestKey("bye")); int i = 0; - for(Parcelable _key : historyBuilder) { + for(Object _key : historyBuilder) { TestKey key = (TestKey) _key; if(i == 0) { assertThat(key.name).isEqualTo("hello"); diff --git a/simple-stack/src/test/java/com/zhuinden/simplestack/ReentranceTest.java b/simple-stack/src/test/java/com/zhuinden/simplestack/ReentranceTest.java index b708eb6d..6f305925 100644 --- a/simple-stack/src/test/java/com/zhuinden/simplestack/ReentranceTest.java +++ b/simple-stack/src/test/java/com/zhuinden/simplestack/ReentranceTest.java @@ -35,7 +35,7 @@ public class ReentranceTest { Backstack flow; - List lastStack; + List lastStack; StateChanger.Callback lastCallback; @Before @@ -358,8 +358,8 @@ static class Error } } - private void verifyHistory(List history, Parcelable... keys) { - List copy = new ArrayList<>(history); + private void verifyHistory(List history, Object... keys) { + List copy = new ArrayList<>(history); Collections.reverse(copy); assertThat(copy).containsExactly(keys); } diff --git a/simple-stack/src/test/java/com/zhuinden/simplestack/StateChangerTest.java b/simple-stack/src/test/java/com/zhuinden/simplestack/StateChangerTest.java index 19feef6e..0b286413 100644 --- a/simple-stack/src/test/java/com/zhuinden/simplestack/StateChangerTest.java +++ b/simple-stack/src/test/java/com/zhuinden/simplestack/StateChangerTest.java @@ -34,8 +34,8 @@ public class StateChangerTest { private static class TestStateChanger implements StateChanger { - private List originalState; - private List newState; + private List originalState; + private List newState; @Override public void handleStateChange(StateChange stateChange, Callback completionCallback) { @@ -315,7 +315,7 @@ public void goBackOneElementReturnsFalse() { @Test public void setHistoryGoesToSetHistory() { - ArrayList newHistory = new ArrayList<>(); + ArrayList newHistory = new ArrayList<>(); newHistory.add(new C()); newHistory.add(new B()); newHistory.add(new D());