Respostas:
Esta é uma solução, embora, como as APIs mudem ao longo do tempo e que haja outras maneiras de fazê-lo, verifique as outras respostas. Um afirma ser mais rápido e outro afirma ser mais fácil.
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());
}
Deixe-me saber se isso funciona.
Recursivamente, basta adicionar as posições superior e esquerda de cada contêiner pai. Você também pode implementá-lo com um Point
se desejar.
A API do Android já fornece um método para conseguir isso. Tente o seguinte:
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;
Aqui está o documento
parentViewGroup
pode ser qualquer pai na hierarquia da exibição, portanto funciona perfeitamente para o ScrollView também.
Por favor, use view.getLocationOnScreen(int[] location);
(consulte Javadocs ). A resposta está na matriz inteira (x = location[0]
e 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];
Primeiro, obtenho o layout raiz e depois calculo a diferença de coordenadas com a visualização.
Você também pode usar o em getLocationOnScreen()
vez de getLocationInWindow()
.
Não há necessidade de calculá-lo manualmente.
Basta usar getGlobalVisibleRect assim:
Rect myViewRect = new Rect();
myView.getGlobalVisibleRect(myViewRect);
float x = myViewRect.left;
float y = myViewRect.top;
Observe também que, para as coordenadas do centro, em vez de algo como:
...
float two = (float) 2
float cx = myViewRect.left + myView.getWidth() / two;
float cy = myViewRect.top + myView.getHeight() / two;
Você pode apenas fazer:
float cx = myViewRect.exactCenterX();
float cy = myViewRect.exactCenterY();
getGlobalVisibleRect
faz é globalOffset.set(-mScrollX, -mScrollY);
que você possa obter esses valores getScollX/Y
se precisar apenas dos coordenados relativos.
Você pode usar `
view.getLocationOnScreen (int [] local)
; `para obter a localização da sua visualização corretamente.
Mas há uma captura , se você usá-lo antes layout foi inflado você receberá posição errada.
A solução para este problema está adicionando ViewTreeObserver
assim: -
Declare globalmente a matriz para armazenar a posição xy da sua visualização
int[] img_coordinates = new int[2];
e adicione ViewTreeObserver
seu layout pai para obter retorno de chamada para inflação do layout e só então buscar a posição da vista, caso contrário, você obterá coordenadas xy erradas
// 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);
}
}
);
e depois use assim
xposition = img_coordinates[0];
yposition = img_coordinates[1];
Escrevi para mim dois métodos utilitários que parecem funcionar na maioria das condições, lidando com rolagem, tradução e redimensionamento, mas não rotação. Fiz isso depois de tentar usar o offsetDescendantRectToMyCoords () na estrutura, que tinha precisão inconsistente. Funcionou em alguns casos, mas deu resultados errados em outros.
"point" é uma matriz flutuante com dois elementos (as coordenadas x e y), "ancestral" é um grupo de visualização em algum lugar acima do "descendente" na hierarquia da árvore.
Primeiro, um método que vai das coordenadas descendentes ao ancestral:
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);
}
}
Em seguida, o inverso, do ancestral ao descendente:
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;
}
Caso alguém ainda esteja tentando descobrir isso. É assim que você obtém o centro X e Y do view
.
int pos[] = new int[2];
view.getLocationOnScreen(pos);
int centerX = pos[0] + view.getMeasuredWidth() / 2;
int centerY = pos[1] + view.getMeasuredHeight() / 2;
Acabei de encontrar a resposta aqui
Ele diz: É possível recuperar a localização de uma exibição invocando os métodos getLeft () e getTop (). O primeiro retorna a coordenada esquerda, ou X, do retângulo que representa a vista. O último retorna a coordenada superior, ou Y, do retângulo que representa a vista. Esses métodos retornam o local da visualização em relação ao pai. Por exemplo, quando getLeft () retorna 20, isso significa que a exibição está localizada 20 pixels à direita da borda esquerda de seu pai direto.
então use:
view.getLeft(); // to get the location of X from left to right
view.getRight()+; // to get the location of Y from right to left