Created
March 30, 2017 06:07
-
-
Save VladSumtsov/a0b23ff895f953f12505d784acbbebd6 to your computer and use it in GitHub Desktop.
Override view states for flow
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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