public final boolean onTouch(View paramView, MotionEvent paramMotionEvent) { if (paramMotionEvent.getAction() == 0) { iXm.eCr = ad.DN(); iXm.gCL = paramView.getScrollY(); iXm.iXl = iXm.gCL; iXm.handler.removeMessages(0); if (iXm.fRZ) { iXm.fRZ = false; iXm.fSa = true; } } while ((paramMotionEvent.getAction() == 2) || ((paramMotionEvent.getAction() != 3) && (paramMotionEvent.getAction() != 1) && (paramMotionEvent.getAction() != 4))) { return false; } if (Math.abs(iXm.iXl - paramView.getScrollY()) > 3) { iXm.handler.sendMessage(iXm.handler.obtainMessage(0, paramView)); } paramMotionEvent = iXm; if ((ad.DN() - eCr < 800L) && (Math.abs(iXm.iXl - paramView.getScrollY()) <= 3) && (!iXm.fSa) && (iXm.cAu != null) && (iXm.cAu.isShowing())) { iXm.handler.removeMessages(0); gf.a(iXm); iXm.cAu.dismiss(); } iXm.fSa = false; return false; }
@Override public boolean onTouchEvent(MotionEvent event) { int x = (int) event.getX(); int y = (int) event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: lastX = (int) event.getX(); lastY = (int) event.getY(); break; case MotionEvent.ACTION_MOVE: int offsetX = x - lastX; int offsetY = y - lastY; ((View) getParent()).scrollBy(-offsetX, -offsetY); break; case MotionEvent.ACTION_UP: // 手指离开时,执行滑动过程 View viewGroup = ((View) getParent()); ScrollerHelper.getScroller() .startScroll( viewGroup.getScrollX(), viewGroup.getScrollY(), -viewGroup.getScrollX(), -viewGroup.getScrollY()); invalidate(); break; } return true; }
/** * Scrolls a ScrollView. * * @param direction the direction to be scrolled * @return {@code true} if scrolling occurred, false if it did not */ boolean scrollView(final View view, int direction) { if (view == null) { return false; } int height = view.getHeight(); height--; int scrollTo = -1; if (direction == DOWN) { scrollTo = height; } else if (direction == UP) { scrollTo = -height; } int originalY = view.getScrollY(); final int scrollAmount = scrollTo; inst.runOnMainSync( new Runnable() { public void run() { view.scrollBy(0, scrollAmount); } }); if (originalY == view.getScrollY()) { return false; } else { return true; } }
@Override public boolean onInterceptTouchEvent(View view, MotionEvent event) { // We need to account for scroll state for the touched view otherwise // tapping on an "empty" part of the view will still be considered a // valid touch event. if (view.getScrollX() != 0 || view.getScrollY() != 0) { Rect rect = new Rect(); view.getHitRect(rect); rect.offset(-view.getScrollX(), -view.getScrollY()); int[] viewCoords = new int[2]; view.getLocationOnScreen(viewCoords); int x = (int) event.getRawX() - viewCoords[0]; int y = (int) event.getRawY() - viewCoords[1]; if (!rect.contains(x, y)) return false; } // If the tab tray is showing, hide the tab tray and don't send the event to content. if (event.getActionMasked() == MotionEvent.ACTION_DOWN && autoHideTabs()) { mIsHidingTabs = true; return true; } return false; }
public static void invalidate(View view) { m_tempRect.set( view.getScrollX(), view.getScrollY(), view.getScrollX() + view.getWidth(), view.getScrollY() + view.getHeight()); view.invalidate(m_tempRect); }
private MemberChip constructChipSpan(User user, int offset, boolean pressed) { LayoutInflater lf = (LayoutInflater) getContext().getSystemService(Activity.LAYOUT_INFLATER_SERVICE); View clipView = lf.inflate(R.layout.member_clip, null); ((TextView) clipView.findViewById(R.id.member_clip)).setText(user.name); int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); clipView.measure(spec, spec); clipView.layout(0, 0, clipView.getMeasuredWidth(), clipView.getMeasuredHeight()); Bitmap b = Bitmap.createBitmap(clipView.getWidth(), clipView.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(b); canvas.translate(-clipView.getScrollX(), -clipView.getScrollY()); clipView.draw(canvas); clipView.setDrawingCacheEnabled(true); Bitmap cacheBmp = clipView.getDrawingCache(); Bitmap viewBmp = cacheBmp.copy(Bitmap.Config.ARGB_8888, true); clipView.destroyDrawingCache(); Drawable result = new BitmapDrawable(getResources(), viewBmp); result.setBounds(0, 0, viewBmp.getWidth(), viewBmp.getHeight()); MemberChip chip = new MemberChip(result, user); return chip; }
@Override public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) { // offset into coordinate space of this scroll view rectangle.offset(child.getLeft() - child.getScrollX(), child.getTop() - child.getScrollY()); return scrollToChildRect(rectangle, immediate); }
/** 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; }
private static boolean isTouchEventHandled(final View view, final MotionEvent event) { if (view instanceof RightPaneBackgroundView) return false; if (!(view instanceof ViewGroup)) return true; final MotionEvent ev = MotionEvent.obtain(event); final float xf = ev.getX(); final float yf = ev.getY(); final float scrolledXFloat = xf + view.getScrollX(); final float scrolledYFloat = yf + view.getScrollY(); final Rect frame = new Rect(); final int scrolledXInt = (int) scrolledXFloat; final int scrolledYInt = (int) scrolledYFloat; final int count = ((ViewGroup) view).getChildCount(); for (int i = count - 1; i >= 0; i--) { final View child = ((ViewGroup) view).getChildAt(i); if (child.isShown() || child.getAnimation() != null) { child.getHitRect(frame); if (frame.contains(scrolledXInt, scrolledYInt)) { // offset the event to the view's coordinate system final float xc = scrolledXFloat - child.getLeft(); final float yc = scrolledYFloat - child.getTop(); ev.setLocation(xc, yc); if (isTouchEventHandled(child, ev)) return true; } } } return false; }
public int getScrollY() { View view = mView.get(); if (view == null) { return 0; } return view.getScrollY(); }
@Test public void shouldScrollTo() throws Exception { view.scrollTo(7, 6); assertEquals(7, view.getScrollX()); assertEquals(6, view.getScrollY()); }
private void initSlideMode() { mCloseOnRelease = false; View v = getChildAt(1); if (mMode == MODE_READY) { mStartOffset = 0; mEndOffset = mDirection * getChildAt(0).getWidth(); } else { mStartOffset = mDirection * getChildAt(0).getWidth(); mEndOffset = 0; } mOffset = mStartOffset; if (mCachedBitmap == null || mCachedBitmap.isRecycled() || mCachedBitmap.getWidth() != v.getWidth()) { mCachedBitmap = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888); mCachedCanvas = new Canvas(mCachedBitmap); } else { mCachedCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); } v.setVisibility(View.VISIBLE); mCachedCanvas.translate(-v.getScrollX(), -v.getScrollY()); v.draw(mCachedCanvas); mMode = MODE_SLIDE; mMenuView.setVisibility(View.VISIBLE); }
public static Bitmap capture( View view, float width, float height, boolean scroll, Bitmap.Config config) { if (!view.isDrawingCacheEnabled()) view.setDrawingCacheEnabled(true); Bitmap bitmap = Bitmap.createBitmap((int) width, (int) height, config); bitmap.eraseColor(Color.WHITE); Canvas canvas = new Canvas(bitmap); int left = view.getLeft(); int top = view.getTop(); if (scroll) { left = view.getScrollX(); top = view.getScrollY(); } int status = canvas.save(); canvas.translate(-left, -top); float scale = width / view.getWidth(); canvas.scale(scale, scale, left, top); view.draw(canvas); canvas.restoreToCount(status); Paint alphaPaint = new Paint(); alphaPaint.setColor(Color.TRANSPARENT); canvas.drawRect(0f, 0f, 1f, height, alphaPaint); canvas.drawRect(width - 1f, 0f, width, height, alphaPaint); canvas.drawRect(0f, 0f, width, 1f, alphaPaint); canvas.drawRect(0f, height - 1f, width, height, alphaPaint); canvas.setBitmap(null); return bitmap; }
/** * 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; }
/** * Crop the image based on the position of the view on the window. Either the View or one of its * ancestors might have scrolled or translated. This value should be taken into account while * mapping the View to the Bitmap. * * @param view The view requesting a cropped bitmap. */ private Bitmap getCroppedBitmap(View view) { if (mBitmap == null || view == null) { return null; } // Get the global position of the view on the entire screen. Rect rect = new Rect(); view.getGlobalVisibleRect(rect); // Get the activity's window position. This does an IPC call, may be expensive. Rect window = new Rect(); view.getWindowVisibleDisplayFrame(window); // Calculate the coordinates for the cropped bitmap. int screenWidth = view.getContext().getResources().getDisplayMetrics().widthPixels; int left = mBitmap.getWidth() - screenWidth + rect.left; int right = mBitmap.getWidth() - screenWidth + rect.right; int top = rect.top - window.top; int bottom = rect.bottom - window.top; int offsetX = 0; int offsetY = 0; // Find if this view or any of its ancestors has been translated or scrolled. ViewParent parent; View curView = view; do { offsetX += (int) curView.getTranslationX() - curView.getScrollX(); offsetY += (int) curView.getTranslationY() - curView.getScrollY(); parent = curView.getParent(); if (parent instanceof View) { curView = (View) parent; } } while (parent instanceof View); // Adjust the coordinates for the offset. left -= offsetX; right -= offsetX; top -= offsetY; bottom -= offsetY; // The either the required height may be less than the available image height or more than it. // If the height required is more, crop only the available portion on the image. int width = right - left; int height = (bottom > mBitmap.getHeight() ? mBitmap.getHeight() - top : bottom - top); // There is a chance that the view is not visible or doesn't fall within the phone's size. // In this case, 'rect' will have all values as '0'. Hence 'top' and 'bottom' may be negative, // and createBitmap() will fail. // The view will get a background in its next layout pass. try { return Bitmap.createBitmap(mBitmap, left, top, width, height); } catch (Exception e) { return null; } }
private boolean canScrollUp(View view, float x, float y) { if (view instanceof ViewGroup) { ViewGroup vg = (ViewGroup) view; for (int i = 0; i < vg.getChildCount(); i++) { View child = vg.getChildAt(i); int childLeft = child.getLeft() - view.getScrollX(); int childTop = child.getTop() - view.getScrollY(); int childRight = child.getRight() - view.getScrollX(); int childBottom = child.getBottom() - view.getScrollY(); boolean intersects = x > childLeft && x < childRight && y > childTop && y < childBottom; if (intersects && canScrollUp(child, x - childLeft, y - childTop)) { return true; } } } return view.canScrollVertically(-1); }
/** 向左滑动 左正右负 */ private void scrollToLeft() { removeDirection = RemoveDirection.LEFT; final int delta = (screenWidth - itemView.getScrollX()); // 调用startScroll方法来设置一些滚动的参数,在computeScroll()方法中调用scrollTo来滚动item // 由(startX , startY)在duration时间内前进(dx,dy)个单位,即到达坐标为(startX+dx , startY+dy)出 scroller.startScroll(itemView.getScrollX(), itemView.getScrollY(), delta, 0, Math.abs(delta)); postInvalidate(); // 刷新itemView 会调用computeScroll()方法 }
/** * Positions the popup window on screen. When the popup window is too tall to fit under the * anchor, a parent scroll view is seeked and scrolled up to reclaim space. If scrolling is not * possible or not enough, the popup window gets moved on top of the anchor. * * <p>The height must have been set on the layout parameters prior to calling this method. * * @param anchor the view on which the popup window must be anchored * @param p the layout parameters used to display the drop down * @return true if the popup is translated upwards to fit on screen */ private boolean findDropDownPosition( View anchor, WindowManager.LayoutParams p, int xoff, int yoff) { anchor.getLocationInWindow(mDrawingLocation); p.x = mDrawingLocation[0] + xoff; p.y = mDrawingLocation[1] + anchor.getMeasuredHeight() + yoff; boolean onTop = false; p.gravity = Gravity.LEFT | Gravity.TOP; anchor.getLocationOnScreen(mScreenLocation); final Rect displayFrame = new Rect(); anchor.getWindowVisibleDisplayFrame(displayFrame); final View root = anchor.getRootView(); if (mScreenLocation[1] + anchor.getMeasuredHeight() + yoff + mPopupHeight > displayFrame.bottom || p.x + mPopupWidth - root.getWidth() > 0) { // if the drop down disappears at the bottom of the screen. we try to // scroll a parent scrollview or move the drop down back up on top of // the edit box int scrollX = anchor.getScrollX(); int scrollY = anchor.getScrollY(); Rect r = new Rect( scrollX, scrollY, scrollX + mPopupWidth, scrollY + mPopupHeight + anchor.getMeasuredHeight()); anchor.requestRectangleOnScreen(r, true); // now we re-evaluate the space available, and decide from that // whether the pop-up will go above or below the anchor. anchor.getLocationInWindow(mDrawingLocation); p.x = mDrawingLocation[0] + xoff; p.y = mDrawingLocation[1] + anchor.getMeasuredHeight() + yoff; // determine whether there is more space above or below the anchor anchor.getLocationOnScreen(mScreenLocation); onTop = (displayFrame.bottom - mScreenLocation[1] - anchor.getMeasuredHeight() - yoff) < (mScreenLocation[1] - yoff - displayFrame.top); if (onTop) { p.gravity = Gravity.LEFT | Gravity.BOTTOM; p.y = root.getHeight() - mDrawingLocation[1] - yoff; } else { p.y = mDrawingLocation[1] + anchor.getMeasuredHeight() + yoff; } } p.gravity |= Gravity.DISPLAY_CLIP_VERTICAL; return onTop; }
/** 检查是否需要处理事件 */ private boolean checkHandleEvent() { if (firstView == null || secondView == null) { return false; } View firstView = this.firstView; View secondView = this.secondView; float firstScrollY = firstView.getScrollY(); // 已经滚动的距离 float secondScrollY = secondView.getScrollY(); // 滚动的距离 if ((firstScrollY + firstViewHeight) == firstViewMaxHeight && offsetTop == 0) { return true; } if (Math.abs(offsetTop) == firstViewHeight && secondScrollY == 0) { return true; } return false; }
public static Bitmap getBitmapFromView(View view, int width, int height) { view.measure( View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY)); view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); canvas.translate(-view.getScrollX(), -view.getScrollY()); view.draw(canvas); return bitmap; }
private void showMenu(View parent, int x, int y) { if (menu == null) { View view = LayoutInflater.from(this).inflate(R.layout.activity_touchintercept_list_item_pop, null); menu = new PopupWindow(view, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, true); TextView replay = (TextView) view.findViewById(R.id.tv_pop_replay); menu.setOutsideTouchable(true); // 设置点击窗口外边窗口消失 ColorDrawable cw = new ColorDrawable(-00000); menu.setBackgroundDrawable(cw); replay.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Toast.makeText(getApplicationContext(), "reply已点击!", Toast.LENGTH_SHORT).show(); menu.dismiss(); } }); } System.out.println("parent.scrolly=" + parent.getScrollY()); menu.showAtLocation(parent, Gravity.TOP | Gravity.LEFT, x, parent.getScrollY() + y); }
public static boolean canChildScrollUp(View view) { if (android.os.Build.VERSION.SDK_INT < 14) { if (view instanceof AbsListView) { final AbsListView absListView = (AbsListView) view; return absListView.getChildCount() > 0 && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0).getTop() < absListView.getPaddingTop()); } else { return view.getScrollY() > 0; } } else { return view.canScrollVertically(-1); } }
@Override public boolean canScrollVertically(int direction) { if (android.os.Build.VERSION.SDK_INT < 14) { if (mTargetView instanceof AdapterView) { return canListScroll(direction); } else { return direction < 0 ? mTargetView.getScrollY() > 0 : mTargetView.getScrollY() < mTargetView.getMeasuredHeight(); } } else { return ViewCompat.canScrollVertically(mTargetView, direction); } }
/** * @return Whether it is possible for the child view of this layout to scroll up. Override this if * the child view is a custom view. */ public boolean canChildScrollUp() { if (android.os.Build.VERSION.SDK_INT < 14) { if (mTarget instanceof AbsListView) { final AbsListView absListView = (AbsListView) mTarget; return absListView.getChildCount() > 0 && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0).getTop() < absListView.getPaddingTop()); } else { return mTarget.getScrollY() > 0; } } else { return ViewCompat.canScrollVertically(mTarget, -1); } }
/** * 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; }
@Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { // Grab the last child placed in the ScrollView, we need it to determinate the bottom position. View view = getChildAt(getChildCount() - 1); if (null != view) { // Calculate the scroll diff int diff = (view.getBottom() - (view.getHeight() + view.getScrollY())); // if diff is zero, then the bottom has been reached if (diff == 0 && mEnableAutoLoad) { // notify that we have reached the bottom startLoadMore(); } } super.onScrollChanged(l, t, oldl, oldt); }
/** * 根据touch事件来滚动View的scrollX * * @param delta */ private void horizontalDrag(int delta) { int scrollX = mTargetView.getScrollX(); int scrollY = mTargetView.getScrollY(); if ((scrollX + delta) <= 0) { mTargetView.scrollTo(0, scrollY); return; } int horRange = getHorizontalRange(); scrollX += delta; if (Math.abs(scrollX) < horRange) { mTargetView.scrollTo(scrollX, scrollY); } else { mTargetView.scrollTo(horRange, scrollY); } }
public boolean canChildScrollDown() { if (android.os.Build.VERSION.SDK_INT < 14) { if (mTarget instanceof AbsListView) { final AbsListView absListView = (AbsListView) mTarget; View lastChild = absListView.getChildAt(absListView.getChildCount() - 1); if (lastChild != null) { return (absListView.getLastVisiblePosition() == (absListView.getCount() - 1)) && lastChild.getBottom() > absListView.getPaddingBottom(); } else { return false; } } else { return mTarget.getHeight() - mTarget.getScrollY() > 0; } } else { return ViewCompat.canScrollVertically(mTarget, 1); } }
public static boolean canViewScrollUp(View view) { if (view == null) { return false; } if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) { if (view instanceof AbsListView) { final AbsListView absListView = (AbsListView) view; if (absListView.getChildCount() == 0) { return false; } return absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0).getTop() < absListView.getPaddingTop(); } else { return view.getScrollY() > 0; } } else { return ViewCompat.canScrollVertically(view, -1); } }
/** * 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; }