/** Inverse of {@link #getDescendantCoordRelativeToSelf(View, int[])}. */
  public static float mapCoordInSelfToDescendent(View descendant, View root, int[] coord) {
    ArrayList<View> ancestorChain = new ArrayList<View>();

    float[] pt = {coord[0], coord[1]};

    View v = descendant;
    while (v != root) {
      ancestorChain.add(v);
      v = (View) v.getParent();
    }
    ancestorChain.add(root);

    float scale = 1.0f;
    Matrix inverse = new Matrix();
    int count = ancestorChain.size();
    for (int i = count - 1; i >= 0; i--) {
      View ancestor = ancestorChain.get(i);
      View next = i > 0 ? ancestorChain.get(i - 1) : null;

      pt[0] += ancestor.getScrollX();
      pt[1] += ancestor.getScrollY();

      if (next != null) {
        pt[0] -= next.getLeft();
        pt[1] -= next.getTop();
        next.getMatrix().invert(inverse);
        inverse.mapPoints(pt);
        scale *= next.getScaleX();
      }
    }

    coord[0] = (int) Math.round(pt[0]);
    coord[1] = (int) Math.round(pt[1]);
    return scale;
  }
  /**
   * Given a coordinate relative to the descendant, find the coordinate in a parent view's
   * coordinates.
   *
   * @param descendant The descendant to which the passed coordinate is relative.
   * @param root The root view to make the coordinates relative to.
   * @param coord The coordinate that we want mapped.
   * @param includeRootScroll Whether or not to account for the scroll of the descendant: sometimes
   *     this is relevant as in a child's coordinates within the descendant.
   * @return The factor by which this descendant is scaled relative to this DragLayer. Caution this
   *     scale factor is assumed to be equal in X and Y, and so if at any point this assumption
   *     fails, we will need to return a pair of scale factors.
   */
  public static float getDescendantCoordRelativeToParent(
      View descendant, View root, int[] coord, boolean includeRootScroll) {
    ArrayList<View> ancestorChain = new ArrayList<View>();

    float[] pt = {coord[0], coord[1]};

    View v = descendant;
    while (v != root && v != null) {
      ancestorChain.add(v);
      v = (View) v.getParent();
    }
    ancestorChain.add(root);

    float scale = 1.0f;
    int count = ancestorChain.size();
    for (int i = 0; i < count; i++) {
      View v0 = ancestorChain.get(i);
      // For TextViews, scroll has a meaning which relates to the text position
      // which is very strange... ignore the scroll.
      if (v0 != descendant || includeRootScroll) {
        pt[0] -= v0.getScrollX();
        pt[1] -= v0.getScrollY();
      }

      v0.getMatrix().mapPoints(pt);
      pt[0] += v0.getLeft();
      pt[1] += v0.getTop();
      scale *= v0.getScaleX();
    }

    coord[0] = (int) Math.round(pt[0]);
    coord[1] = (int) Math.round(pt[1]);
    return scale;
  }
    @Override
    public boolean tryCaptureView(View child, int pointerId) {
      // 如果数据List为空,或者子View不可见,则不予处理
      if (child == bottomLayout
          || dataList == null
          || dataList.size() == 0
          || child.getVisibility() != View.VISIBLE
          || child.getScaleX() <= 1.0f - SCALE_STEP) {
        // 一般来讲,如果拖动的是第三层、或者第四层的View,则直接禁止
        // 此处用getScale的用法来巧妙回避
        return false;
      }

      if (btnLock) {
        return false;
      }

      // 只捕获顶部view(rotation=0)
      int childIndex = viewList.indexOf(child);
      if (childIndex > 0) {
        return false;
      }

      return true;
    }
  public static int[] getCenterDeltaInScreenSpace(View v0, View v1, int[] delta) {
    v0.getLocationInWindow(sLoc0);
    v1.getLocationInWindow(sLoc1);

    sLoc0[0] += (v0.getMeasuredWidth() * v0.getScaleX()) / 2;
    sLoc0[1] += (v0.getMeasuredHeight() * v0.getScaleY()) / 2;
    sLoc1[0] += (v1.getMeasuredWidth() * v1.getScaleX()) / 2;
    sLoc1[1] += (v1.getMeasuredHeight() * v1.getScaleY()) / 2;

    if (delta == null) {
      delta = new int[2];
    }

    delta[0] = sLoc1[0] - sLoc0[0];
    delta[1] = sLoc1[1] - sLoc0[1];

    return delta;
  }
Example #5
0
 /**
  * Given a coordinate relative to the descendant, find the coordinate in this DragLayer's
  * coordinates.
  *
  * @param descendant The descendant to which the passed coordinate is relative.
  * @param coord The coordinate that we want mapped.
  * @return The factor by which this descendant is scaled relative to this DragLayer. Caution this
  *     scale factor is assumed to be equal in X and Y, and so if at any point this assumption
  *     fails, we will need to return a pair of scale factors.
  */
 public float getDescendantCoordRelativeToSelf(View descendant, int[] coord) {
   float scale = 1.0f;
   float[] pt = {coord[0], coord[1]};
   descendant.getMatrix().mapPoints(pt);
   scale *= descendant.getScaleX();
   pt[0] += descendant.getLeft();
   pt[1] += descendant.getTop();
   ViewParent viewParent = descendant.getParent();
   while (viewParent instanceof View && viewParent != this) {
     final View view = (View) viewParent;
     view.getMatrix().mapPoints(pt);
     scale *= view.getScaleX();
     pt[0] += view.getLeft() - view.getScrollX();
     pt[1] += view.getTop() - view.getScrollY();
     viewParent = view.getParent();
   }
   coord[0] = (int) Math.round(pt[0]);
   coord[1] = (int) Math.round(pt[1]);
   return scale;
 }
Example #6
0
  /**
   * Snapshot a view into a Bitmap with the indicated background color.
   *
   * @param view The target {@link android.view.View}.
   * @param backgroundColor The background color of the Bitmap. If the view has transparency areas,
   *     these areas will be erased using this color.
   * @return Returns a Bitmap containing the view content, or {@code null} if any error occurs. Make
   *     sure to call {@link android.graphics.Bitmap#recycle()} as soon as possible, once its
   *     content is not needed anymore.
   */
  public Bitmap snapshotView(View view, int backgroundColor) {
    if (view == null) {
      return null;
    }

    int viewWidth = view.getRight() - view.getLeft();
    int viewHeight = view.getBottom() - view.getTop();

    int sampleWidth = viewWidth / mSampleSize;
    int sampleHeight = viewHeight / mSampleSize;
    float canvasScale = 1.f / mSampleSize;

    sampleWidth = sampleWidth > 0 ? sampleWidth : 1;
    sampleHeight = sampleHeight > 0 ? sampleHeight : 1;

    performanceTickBegin(
        "snapshotView "
            + view
            + " sampleSize = "
            + mSampleSize
            + " ("
            + sampleWidth
            + ", "
            + sampleHeight
            + "): ");

    Bitmap bitmap = Bitmap.createBitmap(sampleWidth, sampleHeight, Bitmap.Config.ARGB_8888);
    if (bitmap == null) {
      throw new OutOfMemoryError();
    }
    if ((backgroundColor & 0xff000000) != 0) {
      bitmap.eraseColor(backgroundColor);
    }

    bitmap.setDensity(mDisplayMetrics.densityDpi);

    Canvas canvas = new Canvas(bitmap);
    canvas.scale(view.getScaleX() * canvasScale, view.getScaleY() * canvasScale);
    canvas.translate(-view.getScrollX(), -view.getScrollY());

    view.computeScroll();
    view.draw(canvas);

    canvas.setBitmap(null);

    performanceTickEnd();

    return bitmap;
  }
Example #7
0
 public static boolean isChildInCenterX(RecyclerView recyclerView, View view) {
   int childCount = recyclerView.getChildCount();
   int[] lvLocationOnScreen = new int[2];
   int[] vLocationOnScreen = new int[2];
   recyclerView.getLocationOnScreen(lvLocationOnScreen);
   int middleX =
       (int) (lvLocationOnScreen[0] + recyclerView.getWidth() * recyclerView.getScaleX() / 2);
   if (childCount > 0) {
     view.getLocationOnScreen(vLocationOnScreen);
     if (vLocationOnScreen[0] <= middleX
         && vLocationOnScreen[0] + view.getWidth() * view.getScaleX() >= middleX) {
       return true;
     }
   }
   return false;
 }
Example #8
0
 public static boolean isItemAtPoint(View view, float x, float y) {
   return (view.getLeft() < x)
       && (view.getLeft() + view.getWidth() * view.getScaleX() > x)
       && (view.getTop() < y)
       && (view.getTop() + view.getHeight() * view.getScaleY() > y);
 }
Example #9
0
  public void animateViewIntoPosition(
      DragView dragView,
      final View child,
      int duration,
      final Runnable onFinishAnimationRunnable,
      View anchorView) {
    ShortcutAndWidgetContainer parentChildren = (ShortcutAndWidgetContainer) child.getParent();
    CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
    parentChildren.measureChild(child);

    Rect r = new Rect();
    getViewRectRelativeToSelf(dragView, r);

    int coord[] = new int[2];
    float childScale = child.getScaleX();
    coord[0] = lp.x + (int) (child.getMeasuredWidth() * (1 - childScale) / 2);
    coord[1] = lp.y + (int) (child.getMeasuredHeight() * (1 - childScale) / 2);

    // Since the child hasn't necessarily been laid out, we force the lp to be updated with
    // the correct coordinates (above) and use these to determine the final location
    float scale = getDescendantCoordRelativeToSelf((View) child.getParent(), coord);
    // We need to account for the scale of the child itself, as the above only accounts for
    // for the scale in parents.
    scale *= childScale;
    int toX = coord[0];
    int toY = coord[1];
    if (child instanceof TextView) {
      TextView tv = (TextView) child;

      // The child may be scaled (always about the center of the view) so to account for it,
      // we have to offset the position by the scaled size.  Once we do that, we can center
      // the drag view about the scaled child view.
      toY += Math.round(scale * tv.getPaddingTop());
      toY -= dragView.getMeasuredHeight() * (1 - scale) / 2;
      toX -= (dragView.getMeasuredWidth() - Math.round(scale * child.getMeasuredWidth())) / 2;
    } else if (child instanceof FolderIcon) {
      // Account for holographic blur padding on the drag view
      toY -= scale * Workspace.DRAG_BITMAP_PADDING / 2;
      toY -= (1 - scale) * dragView.getMeasuredHeight() / 2;
      // Center in the x coordinate about the target's drawable
      toX -= (dragView.getMeasuredWidth() - Math.round(scale * child.getMeasuredWidth())) / 2;
    } else {
      toY -= (Math.round(scale * (dragView.getHeight() - child.getMeasuredHeight()))) / 2;
      toX -= (Math.round(scale * (dragView.getMeasuredWidth() - child.getMeasuredWidth()))) / 2;
    }

    final int fromX = r.left;
    final int fromY = r.top;
    child.setVisibility(INVISIBLE);
    Runnable onCompleteRunnable =
        new Runnable() {
          public void run() {
            child.setVisibility(VISIBLE);
            if (onFinishAnimationRunnable != null) {
              onFinishAnimationRunnable.run();
            }
          }
        };
    animateViewIntoPosition(
        dragView,
        fromX,
        fromY,
        toX,
        toY,
        1,
        1,
        1,
        scale,
        scale,
        onCompleteRunnable,
        ANIMATION_END_DISAPPEAR,
        duration,
        anchorView);
  }
Example #10
0
 public static float getScaleX(View view) {
   return view.getScaleX();
 }
 public static float g(View paramView) {
   return paramView.getScaleX();
 }
 @Override
 public float getScaleX(View view) {
   return view.getScaleX();
 }