Réponses:
C'est une solution, cependant, puisque les API changent avec le temps et qu'il peut y avoir d'autres façons de le faire, assurez-vous de vérifier les autres réponses. L'un prétend être plus rapide et un autre prétend être plus facile.
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());
}
Faites-moi savoir si cela fonctionne.
Il devrait simplement ajouter récursivement les positions supérieure et gauche de chaque conteneur parent. Vous pouvez également l'implémenter avec un Point
si vous le souhaitez.
L'API Android fournit déjà une méthode pour y parvenir. Essaye ça:
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;
Voici le doc
parentViewGroup
peut s'agir de n'importe quel parent dans la hiérarchie des vues, donc cela fonctionne parfaitement pour ScrollView également.
Veuillez utiliser view.getLocationOnScreen(int[] location);
(voir Javadocs ). La réponse est dans le tableau d'entiers (x = location[0]
et 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];
J'obtiens d'abord la disposition racine, puis je calcule la différence de coordonnées avec la vue.
Vous pouvez également utiliser le à la getLocationOnScreen()
place de getLocationInWindow()
.
Pas besoin de le calculer manuellement.
Utilisez simplement getGlobalVisibleRect comme ceci:
Rect myViewRect = new Rect();
myView.getGlobalVisibleRect(myViewRect);
float x = myViewRect.left;
float y = myViewRect.top;
Notez également que pour les coordonnées du centre, plutôt que quelque chose comme:
...
float two = (float) 2
float cx = myViewRect.left + myView.getWidth() / two;
float cy = myViewRect.top + myView.getHeight() / two;
Vous pouvez simplement faire:
float cx = myViewRect.exactCenterX();
float cy = myViewRect.exactCenterY();
getGlobalVisibleRect
est fait globalOffset.set(-mScrollX, -mScrollY);
pour que vous puissiez simplement obtenir ces valeurs avec getScollX/Y
si vous n'avez besoin que des coodinates relatifs.
Vous pouvez utiliser `
view.getLocationOnScreen (int [] emplacement)
; `pour obtenir correctement l'emplacement de votre vue.
Mais il y a une prise si vous utilisez avant la mise en page vous a été gonflé obtiendrez une mauvaise position.
La solution à ce problème est d'ajouter ViewTreeObserver
comme ceci: -
Déclarez globalement le tableau pour stocker la position xy de votre vue
int[] img_coordinates = new int[2];
puis ajoutez ViewTreeObserver
votre mise en page parent pour obtenir un rappel pour l'inflation de la mise en page, puis récupérez la position de la vue, sinon vous obtiendrez de mauvaises coordonnées 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);
}
}
);
puis utilisez-le comme ça
xposition = img_coordinates[0];
yposition = img_coordinates[1];
Je me suis écrit deux méthodes utilitaires qui semblent fonctionner dans la plupart des conditions, la gestion du défilement, de la traduction et de la mise à l'échelle, mais pas de la rotation. Je l'ai fait après avoir essayé d'utiliser offsetDescendantRectToMyCoords () dans le cadre, qui avait une précision incohérente. Cela a fonctionné dans certains cas, mais a donné de mauvais résultats dans d'autres.
"point" est un tableau flottant avec deux éléments (les coordonnées x & y), "ancestor" est un groupe de vues quelque part au-dessus du "descendant" dans la hiérarchie de l'arborescence.
D'abord une méthode qui va des coordonnées descendantes à l'ancêtre:
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);
}
}
Ensuite l'inverse, de l'ancêtre au descendant:
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;
}
Incase quelqu'un essaie toujours de comprendre cela. C'est ainsi que vous obtenez le centre X et Y du view
.
int pos[] = new int[2];
view.getLocationOnScreen(pos);
int centerX = pos[0] + view.getMeasuredWidth() / 2;
int centerY = pos[1] + view.getMeasuredHeight() / 2;
Je viens de trouver la réponse ici
Il dit: Il est possible de récupérer l'emplacement d'une vue en appelant les méthodes getLeft () et getTop (). Le premier renvoie la coordonnée gauche, ou X, du rectangle représentant la vue. Ce dernier retourne la coordonnée supérieure, ou Y, du rectangle représentant la vue. Ces méthodes renvoient toutes deux l'emplacement de la vue par rapport à son parent. Par exemple, lorsque getLeft () renvoie 20, cela signifie que la vue est située à 20 pixels à droite du bord gauche de son parent direct.
alors utilisez:
view.getLeft(); // to get the location of X from left to right
view.getRight()+; // to get the location of Y from right to left