/**
* 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 ancestor 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 getDescendantCoordRelativeToAncestor(
View descendant, View ancestor, int[] coord, boolean includeRootScroll) {
sPoint[0] = coord[0];
sPoint[1] = coord[1];
float scale = 1.0f;
View v = descendant;
while(v != ancestor && v != null) {
// For TextViews, scroll has a meaning which relates to the text position
// which is very strange... ignore the scroll.
if (v != descendant || includeRootScroll) {
sPoint[0] -= v.getScrollX();
sPoint[1] -= v.getScrollY();
}
v.getMatrix().mapPoints(sPoint);
sPoint[0] += v.getLeft();
sPoint[1] += v.getTop();
scale *= v.getScaleX();
v = (View) v.getParent();
}
coord[0] = Math.round(sPoint[0]);
coord[1] = Math.round(sPoint[1]);
return scale;
}
方法1:将子孙descendant上的坐标coord(相对于descendant的坐标,非祖先),映射为相对于祖先ancestor的当前屏幕的坐标。
/**
* Inverse of {@link #getDescendantCoordRelativeToAncestor(View, View, int[], boolean)}.
*/
public static void mapCoordInSelfToDescendant(View descendant, View root, int[] coord) {
sMatrix.reset();
View v = descendant;
while(v != root) {
sMatrix.postTranslate(-v.getScrollX(), -v.getScrollY());
sMatrix.postConcat(v.getMatrix());
sMatrix.postTranslate(v.getLeft(), v.getTop());
v = (View) v.getParent();
}
sMatrix.postTranslate(-v.getScrollX(), -v.getScrollY());
sMatrix.invert(sInverseMatrix);
sPoint[0] = coord[0];
sPoint[1] = coord[1];
sInverseMatrix.mapPoints(sPoint);
coord[0] = Math.round(sPoint[0]);
coord[1] = Math.round(sPoint[1]);
}
方法2:将位于当前子孙descendant上的屏幕坐标coord,映射为最初未进行任何matrix变换的,descendant上的点相对于祖先root的视图坐标(非屏幕坐标)
本文深入探讨了在Android中如何将视图坐标从一个视图转换到另一个视图的坐标系,包括从子孙视图到祖先视图的坐标转换方法及逆过程。详细解释了getDescendantCoordRelativeToAncestor和mapCoordInSelfToDescendant两个核心函数的实现原理。
637

被折叠的 条评论
为什么被折叠?



