/** Resets this TaskStackView for reuse. */ void reset() { // Reset the focused task resetFocusedTask(); // Return all the views to the pool int childCount = getChildCount(); for (int i = childCount - 1; i >= 0; i--) { DeckChildView<T> tv = (DeckChildView) getChildAt(i); mViewPool.returnViewToPool(tv); } // Mark each task view for relayout if (mViewPool != null) { Iterator<DeckChildView<T>> iter = mViewPool.poolViewIterator(); if (iter != null) { while (iter.hasNext()) { DeckChildView tv = iter.next(); tv.reset(); } } } // Reset the stack state mStackViewsDirty = true; mStackViewsClipDirty = true; mAwaitingFirstLayout = true; mPrevAccessibilityFocusedIndex = -1; if (mUIDozeTrigger != null) { mUIDozeTrigger.stopDozing(); mUIDozeTrigger.resetTrigger(); } mStackScroller.reset(); }
@Override public void prepareViewToLeavePool(DeckChildView<T> dcv, T key, boolean isNewView) { // It is possible for a view to be returned to the view pool before it is laid out, // which means that we will need to relayout the view when it is first used next. boolean requiresRelayout = dcv.getWidth() <= 0 && !isNewView; // Rebind the task and request that this task's data be filled into the TaskView dcv.onTaskBound(key); // Load the task data mCallback.loadViewData(new WeakReference<DeckChildView<T>>(dcv), key); // If the doze trigger has already fired, then update the state for this task view if (mUIDozeTrigger.hasTriggered()) { dcv.setNoUserInteractionState(); } // If we've finished the start animation, then ensure we always enable the focus animations if (mStartEnterAnimationCompleted) { dcv.enableFocusAnimations(); } // Find the index where this task should be placed in the stack int insertIndex = -1; int position = mCallback.getData().indexOf(key); if (position != -1) { int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { T otherKey = ((DeckChildView<T>) getChildAt(i)).getAttachedKey(); int pos = mCallback.getData().indexOf(otherKey); if (position < pos) { insertIndex = i; break; } } } // Add/attach the view to the hierarchy if (isNewView) { addView(dcv, insertIndex); } else { attachViewToParent(dcv, insertIndex, dcv.getLayoutParams()); if (requiresRelayout) { dcv.requestLayout(); } } // Set the new state for this view, including the callbacks and view clipping dcv.setCallbacks(this); dcv.setTouchEnabled(true); dcv.setClipViewInStack(true); }
/** Handler for the first layout. */ void onFirstLayout() { int offscreenY = mLayoutAlgorithm.mViewRect.bottom - (mLayoutAlgorithm.mTaskRect.top - mLayoutAlgorithm.mViewRect.top); int childCount = getChildCount(); // Prepare the first view for its enter animation for (int i = childCount - 1; i >= 0; i--) { DeckChildView tv = (DeckChildView) getChildAt(i); // TODO: The false needs to go! tv.prepareEnterRecentsAnimation(i == childCount - 1, false, offscreenY); } // If the enter animation started already and we haven't completed a layout yet, do the // enter animation now if (mStartEnterAnimationRequestedAfterLayout) { startEnterRecentsAnimation(mStartEnterAnimationContext); mStartEnterAnimationRequestedAfterLayout = false; mStartEnterAnimationContext = null; } // When Alt-Tabbing, focus the previous task (but leave the animation until we finish the // enter animation). if (mConfig.launchedWithAltTab) { if (mConfig.launchedFromAppWithThumbnail) { focusTask( Math.max(0, mCallback.getData().size() - 2), false, mConfig.launchedHasConfigurationChanged); } else { focusTask( Math.max(0, mCallback.getData().size() - 1), false, mConfig.launchedHasConfigurationChanged); } } // Start dozing mUIDozeTrigger.startDozing(); }
@Override public void onDeckChildViewClicked(DeckChildView<T> dcv, T key) { // Cancel any doze triggers mUIDozeTrigger.stopDozing(); mCallback.onItemClick(key); }
/** Pokes the dozer on user interaction. */ void onUserInteraction() { // Poke the doze trigger if it is dozing mUIDozeTrigger.poke(); }