Jawaban:
Ini adalah salah satu solusi, meskipun karena API berubah dari waktu ke waktu dan mungkin ada cara lain untuk melakukannya, pastikan untuk memeriksa jawaban lainnya. Satu mengklaim lebih cepat, dan lainnya mengklaim lebih mudah.
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());
}
Beri tahu saya jika itu berhasil.
Seharusnya secara rekursif tambahkan saja posisi atas dan kiri dari setiap wadah induk. Anda juga bisa menerapkannya dengan Point
jika Anda mau.
API Android sudah menyediakan metode untuk mencapainya. Coba ini:
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;
Ini dok
parentViewGroup
dapat berupa orang tua mana pun dalam hierarki tampilan, sehingga berfungsi dengan baik untuk ScrollView juga.
Silakan gunakan view.getLocationOnScreen(int[] location);
(lihat Javadocs ). Jawabannya ada dalam array integer (x = location[0]
dan 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];
Pertama saya mendapatkan tata letak root lalu menghitung selisih koordinat dengan tampilan.
Anda juga dapat menggunakan getLocationOnScreen()
bukan getLocationInWindow()
.
Tidak perlu menghitungnya secara manual.
Cukup gunakan getGlobalVisibleRect seperti:
Rect myViewRect = new Rect();
myView.getGlobalVisibleRect(myViewRect);
float x = myViewRect.left;
float y = myViewRect.top;
Perhatikan juga bahwa untuk koordinat pusat, bukan sesuatu seperti:
...
float two = (float) 2
float cx = myViewRect.left + myView.getWidth() / two;
float cy = myViewRect.top + myView.getHeight() / two;
Anda bisa melakukannya:
float cx = myViewRect.exactCenterX();
float cy = myViewRect.exactCenterY();
getGlobalVisibleRect
dilakukan globalOffset.set(-mScrollX, -mScrollY);
sehingga Anda hanya bisa mendapatkan nilai-nilai itu dengan getScollX/Y
jika Anda hanya membutuhkan koodinat relatif.
Anda bisa menggunakan `
view.getLocationOnScreen (int [] lokasi)
; `untuk mendapatkan lokasi tampilan Anda dengan benar.
Tetapi ada tangkapan jika Anda menggunakannya sebelum tata letak telah meningkat Anda akan mendapatkan posisi yang salah.
Solusi untuk masalah ini adalah menambahkan ViewTreeObserver
seperti ini: -
Deklarasikan secara global array untuk menyimpan posisi tampilan Anda
int[] img_coordinates = new int[2];
dan kemudian menambahkan ViewTreeObserver
pada tata letak induk Anda untuk mendapatkan panggilan balik untuk tata letak inflasi dan hanya kemudian mengambil posisi pandang jika tidak, Anda akan mendapatkan koordinat xy yang salah
// 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);
}
}
);
dan kemudian gunakan seperti ini
xposition = img_coordinates[0];
yposition = img_coordinates[1];
Saya menulis sendiri dua metode utilitas yang tampaknya berfungsi di sebagian besar kondisi, menangani gulir, terjemahan, dan penskalaan, tetapi tidak rotasi. Saya melakukan ini setelah mencoba menggunakan offsetDescendantRectToMyCoords () dalam framework, yang memiliki akurasi tidak konsisten. Ini berhasil dalam beberapa kasus tetapi memberikan hasil yang salah pada yang lain.
"point" adalah array float dengan dua elemen (koordinat x & y), "leluhur" adalah viewgroup di suatu tempat di atas "keturunan" dalam hierarki pohon.
Pertama metode yang beralih dari koordinat turunan ke leluhur:
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);
}
}
Berikutnya kebalikannya, dari leluhur ke keturunan:
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;
}
Memetikan seseorang masih berusaha mencari tahu ini. Ini adalah bagaimana Anda mendapatkan pusat X dan Y dari view
.
int pos[] = new int[2];
view.getLocationOnScreen(pos);
int centerX = pos[0] + view.getMeasuredWidth() / 2;
int centerY = pos[1] + view.getMeasuredHeight() / 2;
Saya baru saja menemukan jawabannya di sini
Bunyinya: Dimungkinkan untuk mengambil lokasi tampilan dengan memanggil metode getLeft () dan getTop (). Yang pertama mengembalikan koordinat kiri, atau X, dari persegi panjang yang mewakili tampilan. Yang terakhir mengembalikan bagian atas, atau Y, mengoordinasikan persegi panjang yang mewakili tampilan. Metode ini keduanya mengembalikan lokasi tampilan relatif ke induknya. Misalnya, ketika getLeft () mengembalikan 20, itu berarti tampilan terletak 20 piksel di sebelah kanan tepi kiri induk langsungnya.
jadi gunakan:
view.getLeft(); // to get the location of X from left to right
view.getRight()+; // to get the location of Y from right to left