ฉันจะได้ตำแหน่ง x และ y ของ View ที่สัมพันธ์กับเค้าโครงรูทของกิจกรรมของฉันใน Android หรือไม่
ฉันจะได้ตำแหน่ง x และ y ของ View ที่สัมพันธ์กับเค้าโครงรูทของกิจกรรมของฉันใน Android หรือไม่
คำตอบ:
นี่เป็นวิธีแก้ไขปัญหาหนึ่งแม้ว่า API จะเปลี่ยนแปลงตลอดเวลาและอาจมีวิธีอื่นในการดำเนินการตรวจสอบให้แน่ใจว่าได้ตรวจสอบคำตอบอื่น ๆ หนึ่งอ้างว่าเป็นเร็วกว่าและอีกอ้างว่าง่ายขึ้น
private int getRelativeLeft(View myView) {
if (myView.getParent() == myView.getRootView())
return myView.getLeft();
else
return myView.getLeft() + getRelativeLeft((View) myView.getParent());
}
private int getRelativeTop(View myView) {
if (myView.getParent() == myView.getRootView())
return myView.getTop();
else
return myView.getTop() + getRelativeTop((View) myView.getParent());
}
แจ้งให้เราทราบหากใช้งานได้
มันควรจะวนซ้ำเพิ่มตำแหน่งบนสุดและซ้ายจากแต่ละคอนเทนเนอร์หลัก คุณสามารถนำไปใช้กับ a Point
ถ้าคุณต้องการ
Android API มีวิธีการที่จะทำให้สำเร็จ ลองสิ่งนี้:
Rect offsetViewBounds = new Rect();
//returns the visible bounds
childView.getDrawingRect(offsetViewBounds);
// calculates the relative coordinates to the parent
parentViewGroup.offsetDescendantRectToMyCoords(childView, offsetViewBounds);
int relativeTop = offsetViewBounds.top;
int relativeLeft = offsetViewBounds.left;
นี่คือเอกสาร
parentViewGroup
สามารถเป็นพาเรนต์ใด ๆ ในลำดับชั้นการดูดังนั้นจึงทำงานได้อย่างสมบูรณ์แบบสำหรับ ScrollView เช่นกัน
กรุณาใช้view.getLocationOnScreen(int[] location);
(ดูJavadocs ) คำตอบอยู่ในอาร์เรย์จำนวนเต็ม (x = location[0]
และ y = location[1]
)
View rootLayout = view.getRootView().findViewById(android.R.id.content);
int[] viewLocation = new int[2];
view.getLocationInWindow(viewLocation);
int[] rootLocation = new int[2];
rootLayout.getLocationInWindow(rootLocation);
int relativeLeft = viewLocation[0] - rootLocation[0];
int relativeTop = viewLocation[1] - rootLocation[1];
ก่อนอื่นฉันจะได้รับเลย์เอาต์รากแล้วคำนวณความแตกต่างของพิกัดด้วยมุมมอง
นอกจากนี้คุณยังสามารถใช้แทนgetLocationOnScreen()
getLocationInWindow()
ไม่จำเป็นต้องคำนวณด้วยตนเอง
เพียงใช้getGlobalVisibleRectอย่างเช่น:
Rect myViewRect = new Rect();
myView.getGlobalVisibleRect(myViewRect);
float x = myViewRect.left;
float y = myViewRect.top;
โปรดทราบด้วยว่าสำหรับจุดศูนย์กลางพิกัดแทนที่จะเป็นสิ่งที่ต้องการ:
...
float two = (float) 2
float cx = myViewRect.left + myView.getWidth() / two;
float cy = myViewRect.top + myView.getHeight() / two;
คุณสามารถทำได้:
float cx = myViewRect.exactCenterX();
float cy = myViewRect.exactCenterY();
getGlobalVisibleRect
ทำ globalOffset.set(-mScrollX, -mScrollY);
เพื่อให้คุณสามารถรับค่าเหล่านั้นด้วยgetScollX/Y
ถ้าคุณเพียงแค่ต้องญาติ coodinates
คุณสามารถใช้ `
view.getLocationOnScreen (int [] ตำแหน่ง)
; `เพื่อให้ได้ตำแหน่งมุมมองของคุณอย่างถูกต้อง
แต่มีการจับถ้าคุณใช้มันก่อนที่จะขยายรูปแบบที่สูงเกินจริงคุณจะผิด
ทางออกสำหรับปัญหานี้คือการเพิ่มViewTreeObserver
เช่นนี้: -
ประกาศอาร์เรย์ทั่วโลกเพื่อจัดเก็บตำแหน่ง xy ของมุมมองของคุณ
int[] img_coordinates = new int[2];
แล้วเพิ่มลงViewTreeObserver
ในเค้าโครงแม่ของคุณเพื่อเรียกกลับสำหรับเค้าโครงเงินเฟ้อและจากนั้นดึงตำแหน่งมุมมองมิฉะนั้นคุณจะได้รับพิกัด xy ที่ผิด
// set a global layout listener which will be called when the layout pass is completed and the view is drawn
parentViewGroup.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
//Remove the listener before proceeding
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
parentViewGroup.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
parentViewGroup.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
// measure your views here
fab.getLocationOnScreen(img_coordinates);
}
}
);
แล้วใช้มันแบบนี้
xposition = img_coordinates[0];
yposition = img_coordinates[1];
ฉันเขียนตัวเองสองวิธีอรรถประโยชน์ที่ดูเหมือนจะทำงานในเงื่อนไขส่วนใหญ่จัดการเลื่อนแปลและปรับ แต่ไม่หมุน ฉันทำสิ่งนี้หลังจากพยายามใช้ offsetDescendantRectToMyCoords () ในกรอบซึ่งมีความแม่นยำที่ไม่สอดคล้องกัน มันทำงานได้ในบางกรณี แต่ให้ผลลัพธ์ที่ผิดในคนอื่น ๆ
"point" เป็นอาร์เรย์ลอยที่มีสององค์ประกอบ (พิกัด x & y) "บรรพบุรุษ" เป็นกลุ่มดูที่ใดที่หนึ่งเหนือ "ลูกหลาน" ในลำดับชั้นต้นไม้
วิธีแรกที่เปลี่ยนจากพิกัดผู้สืบทอดไปยังบรรพบุรุษ:
public static void transformToAncestor(float[] point, final View ancestor, final View descendant) {
final float scrollX = descendant.getScrollX();
final float scrollY = descendant.getScrollY();
final float left = descendant.getLeft();
final float top = descendant.getTop();
final float px = descendant.getPivotX();
final float py = descendant.getPivotY();
final float tx = descendant.getTranslationX();
final float ty = descendant.getTranslationY();
final float sx = descendant.getScaleX();
final float sy = descendant.getScaleY();
point[0] = left + px + (point[0] - px) * sx + tx - scrollX;
point[1] = top + py + (point[1] - py) * sy + ty - scrollY;
ViewParent parent = descendant.getParent();
if (descendant != ancestor && parent != ancestor && parent instanceof View) {
transformToAncestor(point, ancestor, (View) parent);
}
}
ถัดจากการผกผันจากบรรพบุรุษถึงผู้สืบทอด:
public static void transformToDescendant(float[] point, final View ancestor, final View descendant) {
ViewParent parent = descendant.getParent();
if (descendant != ancestor && parent != ancestor && parent instanceof View) {
transformToDescendant(point, ancestor, (View) parent);
}
final float scrollX = descendant.getScrollX();
final float scrollY = descendant.getScrollY();
final float left = descendant.getLeft();
final float top = descendant.getTop();
final float px = descendant.getPivotX();
final float py = descendant.getPivotY();
final float tx = descendant.getTranslationX();
final float ty = descendant.getTranslationY();
final float sx = descendant.getScaleX();
final float sy = descendant.getScaleY();
point[0] = px + (point[0] + scrollX - left - tx - px) / sx;
point[1] = py + (point[1] + scrollY - top - ty - py) / sy;
}
ในกรณีที่มีใครบางคนยังคงพยายามที่จะคิดออก นี่คือวิธีที่คุณจะได้รับศูนย์ X และ Y view
ของ
int pos[] = new int[2];
view.getLocationOnScreen(pos);
int centerX = pos[0] + view.getMeasuredWidth() / 2;
int centerY = pos[1] + view.getMeasuredHeight() / 2;
ฉันเพิ่งพบคำตอบที่นี่
มันบอกว่า: เป็นไปได้ที่จะดึงตำแหน่งของมุมมองโดยเรียกใช้เมธอด getLeft () และ getTop () อดีตส่งกลับทางซ้ายหรือ X พิกัดของสี่เหลี่ยมผืนผ้าแทนมุมมอง หลังส่งกลับด้านบนหรือ Y พิกัดของสี่เหลี่ยมผืนผ้าแทนมุมมอง เมธอดเหล่านี้จะส่งคืนตำแหน่งของมุมมองที่สัมพันธ์กับพาเรนต์ ตัวอย่างเช่นเมื่อ getLeft () ส่งคืน 20 นั่นหมายความว่ามุมมองจะอยู่ที่ 20 พิกเซลทางด้านขวาของขอบด้านซ้ายของพาเรนต์โดยตรง
เพื่อใช้:
view.getLeft(); // to get the location of X from left to right
view.getRight()+; // to get the location of Y from right to left