Skip to content

Instantly share code, notes, and snippets.

@VladSumtsov
Created March 30, 2017 06:07
Show Gist options
  • Save VladSumtsov/a0b23ff895f953f12505d784acbbebd6 to your computer and use it in GitHub Desktop.
Save VladSumtsov/a0b23ff895f953f12505d784acbbebd6 to your computer and use it in GitHub Desktop.
Override view states for flow
package de.dom.android.ui.util;
import android.content.Context;
import android.os.Parcelable;
import android.util.SparseArray;
import android.view.View;
import java.lang.reflect.Field;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Iterator;
import flow.Flow;
import flow.History;
import flow.ViewState;
/**
* Overrides history view states. When we set history with {@code Flow.setHistory} Flow removes view states from history.
* Use this method to restore these states.
*/
public class FlowUtils {
public static void updateHistoryViewState(History history, Context context) {
Iterator<ViewState> iterator = getHistoryEntries(history).iterator();
Iterator<ViewState> newIterator = getHistoryEntries(Flow.get(context).getHistory()).iterator();
FlowStateView flowState = new FlowStateView(context);
while (iterator.hasNext() && newIterator.hasNext()) {
if (iterator.hasNext() != newIterator.hasNext()) {
throw new IllegalAccessError("to override history view state, list should be the same");
}
ViewState oldViewState = iterator.next();
ViewState newViewState = newIterator.next();
oldViewState.restore(flowState);
newViewState.save(flowState);
}
}
private static Deque<ViewState> getHistoryEntries(History history) {
try {
Field historyField = History.class.getDeclaredField("history");
historyField.setAccessible(true);
return (Deque<ViewState>) historyField.get(history);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
return new ArrayDeque<>(0);
}
/**
* Hack to restore view state to new history.
*/
private static class FlowStateView extends View {
private SparseArray<Parcelable> state;
public FlowStateView(Context context) {
super(context);
}
@Override public void saveHierarchyState(SparseArray<Parcelable> container) {
if (state == null) {
return;
}
for (int i = 0; i < state.size(); i++) {
int key = state.keyAt(i);
container.put(key, state.get(key));
}
}
@Override public void restoreHierarchyState(SparseArray<Parcelable> container) {
state = container;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment