Antworten:
Dies ist eine Lösung. Da sich APIs im Laufe der Zeit ändern und es möglicherweise andere Möglichkeiten gibt, sollten Sie die anderen Antworten überprüfen. Einer behauptet, schneller zu sein, und ein anderer behauptet, einfacher zu sein.
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());
}
Lassen Sie mich wissen, ob das funktioniert.
Es sollte rekursiv nur die obere und linke Position von jedem übergeordneten Container hinzugefügt werden. Sie können es auch mit einem implementieren, Point
wenn Sie möchten.
Die Android-API bietet bereits eine Methode, um dies zu erreichen. Versuche dies:
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;
Hier ist das Dokument
parentViewGroup
funktioniert , möchte nur erwähnen, dass es sich um ein beliebiges übergeordnetes Element in der Ansichtshierarchie handeln kann, sodass es auch für ScrollView perfekt funktioniert.
Bitte benutzen Sie view.getLocationOnScreen(int[] location);
(siehe Javadocs ). Die Antwort liegt im Integer-Array (x = location[0]
und 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];
Zuerst erhalte ich das Root-Layout und berechne dann die Koordinatendifferenz mit der Ansicht.
Sie können auch die getLocationOnScreen()
anstelle von verwenden getLocationInWindow()
.
Sie müssen es nicht manuell berechnen.
Verwenden Sie einfach getGlobalVisibleRect wie folgt :
Rect myViewRect = new Rect();
myView.getGlobalVisibleRect(myViewRect);
float x = myViewRect.left;
float y = myViewRect.top;
Beachten Sie auch, dass für die Mittelkoordinaten eher als:
...
float two = (float) 2
float cx = myViewRect.left + myView.getWidth() / two;
float cy = myViewRect.top + myView.getHeight() / two;
Sie können einfach tun:
float cx = myViewRect.exactCenterX();
float cy = myViewRect.exactCenterY();
getGlobalVisibleRect
tun , ist , globalOffset.set(-mScrollX, -mScrollY);
so dass Sie nur diese Werte mit bekommen könnten , getScollX/Y
wenn Sie brauchen , um den relativen von Koordinaten.
Sie können `verwenden
view.getLocationOnScreen (int [] location)
; `um den Ort Ihrer Ansicht korrekt zu ermitteln.
Aber es gibt einen Haken, wenn Sie es verwenden, bevor das Layout aufgeblasen wurde, erhalten Sie eine falsche Position.
Die Lösung für dieses Problem besteht darin, Folgendes hinzuzufügen ViewTreeObserver
: -
Deklarieren Sie das Array global, um die xy-Position Ihrer Ansicht zu speichern
int[] img_coordinates = new int[2];
Fügen ViewTreeObserver
Sie dann Ihr übergeordnetes Layout hinzu, um einen Rückruf für das Aufblasen des Layouts zu erhalten, und rufen Sie erst dann die Position der Ansicht ab, da sonst falsche xy-Koordinaten angezeigt werden
// 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);
}
}
);
und dann benutze es so
xposition = img_coordinates[0];
yposition = img_coordinates[1];
Ich habe mir zwei Dienstprogrammmethoden geschrieben, die unter den meisten Bedingungen zu funktionieren scheinen: Scrollen, Übersetzen und Skalieren, aber nicht Drehen. Ich habe dies getan, nachdem ich versucht hatte, offsetDescendantRectToMyCoords () im Framework zu verwenden, das eine inkonsistente Genauigkeit aufwies. In einigen Fällen funktionierte es, in anderen gab es falsche Ergebnisse.
"point" ist ein Float-Array mit zwei Elementen (den x & y-Koordinaten). "ancestor" ist eine Ansichtsgruppe irgendwo über dem "Nachkommen" in der Baumhierarchie.
Zuerst eine Methode, die von den Nachkommenkoordinaten zum Vorfahren geht:
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);
}
}
Als nächstes die Umkehrung vom Vorfahren zum Nachkommen:
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;
}
Falls jemand immer noch versucht, dies herauszufinden. So erhalten Sie das Zentrum X und Y des view
.
int pos[] = new int[2];
view.getLocationOnScreen(pos);
int centerX = pos[0] + view.getMeasuredWidth() / 2;
int centerY = pos[1] + view.getMeasuredHeight() / 2;
Ich habe gerade die Antwort hier gefunden
Es heißt: Es ist möglich, den Speicherort einer Ansicht durch Aufrufen der Methoden getLeft () und getTop () abzurufen. Ersteres gibt die linke oder X-Koordinate des Rechtecks zurück, das die Ansicht darstellt. Letzteres gibt die obere oder Y-Koordinate des Rechtecks zurück, das die Ansicht darstellt. Diese Methoden geben beide die Position der Ansicht relativ zu ihrer übergeordneten Ansicht zurück. Wenn getLeft () beispielsweise 20 zurückgibt, bedeutet dies, dass sich die Ansicht 20 Pixel rechts vom linken Rand ihres direkten übergeordneten Elements befindet.
Verwenden Sie also:
view.getLeft(); // to get the location of X from left to right
view.getRight()+; // to get the location of Y from right to left