Skip to content

Commit

Permalink
1.1.0: add KeyParceler interface for custom parcel strategy
Browse files Browse the repository at this point in the history
  • Loading branch information
Zhuinden committed Feb 18, 2017
1 parent 24ccb80 commit 4ef46b5
Show file tree
Hide file tree
Showing 21 changed files with 269 additions and 188 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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!
Expand Down
26 changes: 15 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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?

Expand Down Expand Up @@ -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<Parcelable>`.

- [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<Parcelable>`.
- [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.



Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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) {
Expand All @@ -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())) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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) {
Expand All @@ -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())) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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) {
Expand All @@ -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())) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.example.stackmasterdetailfrag.util;

import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

Expand All @@ -25,13 +24,13 @@ public MasterDetailBackstackDelegate(@Nullable StateChanger stateChanger) {
}

@Override
protected void clearStatesNotIn(@NonNull Map<Parcelable, SavedState> keyStateMap, @NonNull StateChange stateChange) {
Set<Parcelable> keys = keyStateMap.keySet();
Iterator<Parcelable> keyIterator = keys.iterator();
protected void clearStatesNotIn(@NonNull Map<Object, SavedState> keyStateMap, @NonNull StateChange stateChange) {
Set<Object> keys = keyStateMap.keySet();
Iterator<Object> 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;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.example.stackmasterdetail.util;

import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

Expand All @@ -25,13 +24,13 @@ public MasterDetailBackstackDelegate(@Nullable StateChanger stateChanger) {
}

@Override
protected void clearStatesNotIn(@NonNull Map<Parcelable, SavedState> keyStateMap, @NonNull StateChange stateChange) {
Set<Parcelable> keys = keyStateMap.keySet();
Iterator<Parcelable> keyIterator = keys.iterator();
protected void clearStatesNotIn(@NonNull Map<Object, SavedState> keyStateMap, @NonNull StateChange stateChange) {
Set<Object> keys = keyStateMap.keySet();
Iterator<Object> 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;
Expand Down
Loading

0 comments on commit 4ef46b5

Please sign in to comment.