예제 #1
0
  /** Synchronizes the views with the model */
  boolean synchronizeStackViewsWithModel() {
    if (mStackViewsDirty) {
      // Get all the task transforms
      ArrayList<T> data = mCallback.getData();
      float stackScroll = mStackScroller.getStackScroll();
      int[] visibleRange = mTmpVisibleRange;
      boolean isValidVisibleRange =
          updateStackTransforms(mCurrentTaskTransforms, data, stackScroll, visibleRange, false);

      // Return all the invisible children to the pool
      mTmpTaskViewMap.clear();
      int childCount = getChildCount();
      for (int i = childCount - 1; i >= 0; i--) {
        DeckChildView<T> tv = (DeckChildView) getChildAt(i);
        T key = tv.getAttachedKey();
        int taskIndex = data.indexOf(key);

        if (visibleRange[1] <= taskIndex && taskIndex <= visibleRange[0]) {
          mTmpTaskViewMap.put(key, tv);
        } else {
          mViewPool.returnViewToPool(tv);
        }
      }

      for (int i = visibleRange[0]; isValidVisibleRange && i >= visibleRange[1]; i--) {
        T key = data.get(i);
        DeckChildViewTransform transform = mCurrentTaskTransforms.get(i);
        DeckChildView tv = mTmpTaskViewMap.get(key);

        if (tv == null) {
          // TODO Check
          tv = mViewPool.pickUpViewFromPool(key, key);

          if (mStackViewsAnimationDuration > 0) {
            // For items in the list, put them in start animating them from the
            // approriate ends of the list where they are expected to appear
            if (Float.compare(transform.p, 0f) <= 0) {
              mLayoutAlgorithm.getStackTransform(0f, 0f, mTmpTransform, null);
            } else {
              mLayoutAlgorithm.getStackTransform(1f, 0f, mTmpTransform, null);
            }
            tv.updateViewPropertiesToTaskTransform(mTmpTransform, 0);
          }
        }

        // Animate the task into place
        tv.updateViewPropertiesToTaskTransform(
            mCurrentTaskTransforms.get(i),
            mStackViewsAnimationDuration,
            mRequestUpdateClippingListener);
      }

      // Reset the request-synchronize params
      mStackViewsAnimationDuration = 0;
      mStackViewsDirty = false;
      mStackViewsClipDirty = true;
      return true;
    }
    return false;
  }
예제 #2
0
  /** Gets the stack transforms of a list of tasks, and returns the visible range of tasks. */
  private boolean updateStackTransforms(
      ArrayList<DeckChildViewTransform> taskTransforms,
      ArrayList<T> data,
      float stackScroll,
      int[] visibleRangeOut,
      boolean boundTranslationsToRect) {
    int taskTransformCount = taskTransforms.size();
    int taskCount = data.size();
    int frontMostVisibleIndex = -1;
    int backMostVisibleIndex = -1;

    // We can reuse the task transforms where possible to reduce object allocation
    if (taskTransformCount < taskCount) {
      // If there are less transforms than tasks, then add as many transforms as necessary
      for (int i = taskTransformCount; i < taskCount; i++) {
        taskTransforms.add(new DeckChildViewTransform());
      }
    } else if (taskTransformCount > taskCount) {
      // If there are more transforms than tasks, then just subset the transform list
      taskTransforms.subList(0, taskCount);
    }

    // Update the stack transforms
    DeckChildViewTransform prevTransform = null;
    for (int i = taskCount - 1; i >= 0; i--) {
      DeckChildViewTransform transform =
          mLayoutAlgorithm.getStackTransform(
              data.get(i), stackScroll, taskTransforms.get(i), prevTransform);
      if (transform.visible) {
        if (frontMostVisibleIndex < 0) {
          frontMostVisibleIndex = i;
        }
        backMostVisibleIndex = i;
      } else {
        if (backMostVisibleIndex != -1) {
          // We've reached the end of the visible range, so going down the rest of the
          // stack, we can just reset the transforms accordingly
          while (i >= 0) {
            taskTransforms.get(i).reset();
            i--;
          }
          break;
        }
      }

      if (boundTranslationsToRect) {
        transform.translationY =
            Math.min(transform.translationY, mLayoutAlgorithm.mViewRect.bottom);
      }
      prevTransform = transform;
    }
    if (visibleRangeOut != null) {
      visibleRangeOut[0] = frontMostVisibleIndex;
      visibleRangeOut[1] = backMostVisibleIndex;
    }
    return frontMostVisibleIndex != -1 && backMostVisibleIndex != -1;
  }
예제 #3
0
  /** Requests this task stacks to start it's enter-recents animation */
  public void startEnterRecentsAnimation(ViewAnimation.TaskViewEnterContext ctx) {
    // If we are still waiting to layout, then just defer until then
    if (mAwaitingFirstLayout) {
      mStartEnterAnimationRequestedAfterLayout = true;
      mStartEnterAnimationContext = ctx;
      return;
    }

    if (mCallback.getData().size() > 0) {
      int childCount = getChildCount();

      // Animate all the task views into view
      for (int i = childCount - 1; i >= 0; i--) {
        DeckChildView<T> tv = (DeckChildView) getChildAt(i);
        T key = tv.getAttachedKey();
        ctx.currentTaskTransform = new DeckChildViewTransform();
        ctx.currentStackViewIndex = i;
        ctx.currentStackViewCount = childCount;
        ctx.currentTaskRect = mLayoutAlgorithm.mTaskRect;
        // TODO: this needs to go
        ctx.currentTaskOccludesLaunchTarget = false;
        ctx.updateListener = mRequestUpdateClippingListener;
        mLayoutAlgorithm.getStackTransform(
            key, mStackScroller.getStackScroll(), ctx.currentTaskTransform, null);
        tv.startEnterRecentsAnimation(ctx);
      }

      // Add a runnable to the post animation ref counter to clear all the views
      ctx.postAnimationTrigger.addLastDecrementRunnable(
          new Runnable() {
            @Override
            public void run() {
              mStartEnterAnimationCompleted = true;
              // Poke the dozer to restart the trigger after the animation completes
              mUIDozeTrigger.poke();
            }
          });
    }
  }