public void notifyDataSetChanged() { // Get the stack scroll of the task to anchor to (since we are removing something, the front // most task will be our anchor task) T anchorTask = null; float prevAnchorTaskScroll = 0; boolean pullStackForward = mCallback.getData().size() > 0; if (pullStackForward) { anchorTask = mCallback.getData().get(mCallback.getData().size() - 1); prevAnchorTaskScroll = mLayoutAlgorithm.getStackScrollForTask(anchorTask); } // Update the min/max scroll and animate other task views into their new positions updateMinMaxScroll(true, mConfig.launchedWithAltTab, mConfig.launchedFromHome); // Offset the stack by as much as the anchor task would otherwise move back if (pullStackForward) { float anchorTaskScroll = mLayoutAlgorithm.getStackScrollForTask(anchorTask); mStackScroller.setStackScroll( mStackScroller.getStackScroll() + (anchorTaskScroll - prevAnchorTaskScroll)); mStackScroller.boundScroll(); } // Animate all the tasks into place requestSynchronizeStackViewsWithModel(200); T newFrontMostTask = mCallback.getData().size() > 0 ? mCallback.getData().get(mCallback.getData().size() - 1) : null; // Update the new front most task if (newFrontMostTask != null) { DeckChildView<T> frontTv = getChildViewForTask(newFrontMostTask); if (frontTv != null) { frontTv.onTaskBound(newFrontMostTask); } } // If there are no remaining tasks if (mCallback.getData().size() == 0) { mCallback.onNoViewsToDeck(); } }
/** Focuses the task at the specified index in the stack */ public void scrollToChild(int childIndex) { if (getCurrentChildIndex() == childIndex) return; if (0 <= childIndex && childIndex < mCallback.getData().size()) { // Scroll the view into position (just center it in the curve) float newScroll = mLayoutAlgorithm.getStackScrollForTask(mCallback.getData().get(childIndex)) - 0.5f; newScroll = mStackScroller.getBoundedStackScroll(newScroll); mStackScroller.setStackScroll(newScroll); // Alternate (animated) way // mStackScroller.animateScroll(mStackScroller.getStackScroll(), newScroll, null); } }
/** Focuses the task at the specified index in the stack */ void focusTask(int childIndex, boolean scrollToNewPosition, final boolean animateFocusedState) { // Return early if the task is already focused if (childIndex == mFocusedTaskIndex) return; ArrayList<T> data = mCallback.getData(); if (0 <= childIndex && childIndex < data.size()) { mFocusedTaskIndex = childIndex; // Focus the view if possible, otherwise, focus the view after we scroll into position T key = data.get(childIndex); DeckChildView tv = getChildViewForTask(key); Runnable postScrollRunnable = null; if (tv != null) { tv.setFocusedTask(animateFocusedState); } else { postScrollRunnable = new Runnable() { @Override public void run() { DeckChildView tv = getChildViewForTask(mCallback.getData().get(mFocusedTaskIndex)); if (tv != null) { tv.setFocusedTask(animateFocusedState); } } }; } // Scroll the view into position (just center it in the curve) if (scrollToNewPosition) { float newScroll = mLayoutAlgorithm.getStackScrollForTask(key) - 0.5f; newScroll = mStackScroller.getBoundedStackScroll(newScroll); mStackScroller.animateScroll( mStackScroller.getStackScroll(), newScroll, postScrollRunnable); } else { if (postScrollRunnable != null) { postScrollRunnable.run(); } } } }