Pregunta

Estoy intentando obtener las coordenadas absolutas de píxeles de la pantalla de la esquina superior izquierda de una vista.Sin embargo, todos los métodos que puedo encontrar, como getLeft() y getRight() no funcionan ya que todos parecen ser relativos al padre de la vista, lo que me da 0.¿Cuál es la forma apropiada de hacer esto?

Si te ayuda, esto es para un juego de "poner la imagen en orden".Quiero que el usuario pueda dibujar un cuadro para seleccionar varias piezas.Mi suposición es que la forma más fácil de hacerlo es getRawX() y getRawY() desde el MotionEvent y luego compare esos valores con la esquina superior izquierda del diseño que contiene las piezas.Conociendo el tamaño de las piezas, puedo determinar cuántas piezas se han seleccionado.Me doy cuenta de que puedo usar getX() y getY() sobre el MotionEvent, pero eso devuelve una posición relativa que hace que sea más difícil determinar qué piezas se seleccionaron.(No es imposible, lo sé, pero parece innecesariamente complicado).

Editar:Este es el código que utilicé para intentar obtener el tamaño del contenedor, según una de las preguntas. TableLayout es la mesa que contiene todas las piezas del rompecabezas.

TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayout);
Log.d(LOG_TAG, "Values " + tableLayout.getTop() + tableLayout.getLeft());

Edición 2:Aquí está el código que probé, siguiendo más de las respuestas sugeridas.

public int[] tableLayoutCorners = new int[2];
(...)

TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayout);
tableLayout.requestLayout();
Rect corners = new Rect();
tableLayout.getLocalVisibleRect(corners);
Log.d(LOG_TAG, "Top left " + corners.top + ", " + corners.left + ", " + corners.right
            + ", " + corners.bottom);

cells[4].getLocationOnScreen(tableLayoutCorners);
Log.d(LOG_TAG, "Values " + tableLayoutCorners[0] + ", " + tableLayoutCorners[1]);

Este código se agregó después de realizar toda la inicialización.La imagen se ha dividido en una matriz de ImageViews (la matriz de celdas []) contenida dentro de un TableLayout.Celdas [0] es la parte superior izquierda ImageView, y elegí las celdas [4] porque están en algún punto intermedio y definitivamente no deberían tener coordenadas de (0,0).

El código que se muestra arriba todavía me da todos los 0 en los registros, lo cual realmente no entiendo porque las distintas piezas del rompecabezas se muestran correctamente.(Probé public int para tableLayoutCorners y visibilidad predeterminada, y ambos dieron el mismo resultado).

No sé si esto es significativo, pero el ImageViewA los s originalmente no se les da un tamaño.El tamaño de la ImageViews se determina automáticamente durante la inicialización mediante la Vista cuando le doy una imagen para mostrar.¿Podría esto contribuir a que sus valores sean 0, aunque ese código de registro se realice después de que se les haya proporcionado una imagen y hayan cambiado de tamaño automáticamente?Para potencialmente contrarrestar eso, agregué el código tableLayout.requestLayout() como se muestra arriba, pero eso no ayudó.

¿Fue útil?

Otros consejos

La respuesta aceptada en realidad no dice cómo obtener la ubicación, por lo que aquí es un poco más de detalle. Se pasa de una matriz int de longitud 2 y los valores se sustituyen con (x, y) las coordenadas de la vista (de la esquina superior izquierda).

int[] location = new int[2];
myView.getLocationOnScreen(location);
int x = location[0];
int y = location[1];

Notas

  • getLocationOnScreen con getLocationInWindow deberían dar los mismos resultados en la mayoría de los casos ( ver esta respuesta ). Sin embargo, si se encuentra en una ventana más pequeña como un diálogo o teclado personalizado, a continuación, utilizar tendrá que elegir la que mejor se adapta a sus necesidades.
  • Usted recibirá (0,0) si se llama a este método en onCreate porque la vista no se ha presentado todavía. Puede utilizar un ViewTreeObserver para escuchar cuando se hace el diseño y se puede obtener las coordenadas medidas. (Ver esta respuesta .)

Primero tienes que obtener el rectángulo localVisible de la vista.

Por ejemplo:

Rect rectf = new Rect();

//For coordinates location relative to the parent
anyView.getLocalVisibleRect(rectf);

//For coordinates location relative to the screen/display
anyView.getGlobalVisibleRect(rectf);

Log.d("WIDTH        :", String.valueOf(rectf.width()));
Log.d("HEIGHT       :", String.valueOf(rectf.height()));
Log.d("left         :", String.valueOf(rectf.left));
Log.d("right        :", String.valueOf(rectf.right));
Log.d("top          :", String.valueOf(rectf.top));
Log.d("bottom       :", String.valueOf(rectf.bottom));

Espero que esto ayude

El uso de un oyente diseño mundial siempre ha funcionado bien para mí. Tiene la ventaja de ser capaz de volver a medir las cosas si se cambia el diseño, por ejemplo, si algo se establece en View.GONE o se añaden puntos de vista del niño / eliminado.

public void onCreate(Bundle savedInstanceState)
{
     super.onCreate(savedInstanceState);

     // inflate your main layout here (use RelativeLayout or whatever your root ViewGroup type is
     LinearLayout mainLayout = (LinearLayout ) this.getLayoutInflater().inflate(R.layout.main, null); 

     // set a global layout listener which will be called when the layout pass is completed and the view is drawn
     mainLayout.getViewTreeObserver().addOnGlobalLayoutListener(
       new ViewTreeObserver.OnGlobalLayoutListener() {
          public void onGlobalLayout() {
               //Remove the listener before proceeding
               if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    mainLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
               } else {
                    mainLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
               }

               // measure your views here
          }
       }
     );

     setContentView(mainLayout);
 }

Siguiendo el comentario de Romain individuo, así es como me fijo. Es de esperar que va a ayudar a cualquier otra persona que también tenía este problema.

Yo estaba de hecho tratando de obtener las posiciones de los puntos de vista antes de que hubieran sido presentados en la pantalla, pero no era en absoluto obvio que estaba ocurriendo. Esas líneas se habían colocado después del código initilisation funcionó, así que supuse que todo estaba listo. Sin embargo, este código todavía estaba en onCreate (); mediante la experimentación con Thread.sleep () descubrí que el diseño no es en realidad finalizó hasta después onCreate () todo el camino a onResume () había terminado de ejecutarse. Así que de hecho, el código estaba tratando de correr antes de la presentación había terminado de ser colocado en la pantalla. Al añadir el código a un OnClickListener (o algún otro oyente) se obtuvieron los valores correctos, ya que sólo podría ser despedido después de que el diseño había terminado.


La línea de abajo fue sugerido como una comunidad de edición:

por favor utilice onWindowfocuschanged(boolean hasFocus)

Primera forma:

Kotlin podemos crear una simple extensión de la vista:

fun View.getLocationOnScreen(): Point
{
    val location = IntArray(2)
    this.getLocationOnScreen(location)
    return Point(location[0],location[1])
}

Y simplemente obtener coordenadas:

val location = yourView.getLocationOnScreen()
val absX = location.x
val absY = location.y

segunda manera:

La segunda forma es más sencilla:

fun View.absX(): Int
{
    val location = IntArray(2)
    this.getLocationOnScreen(location)
    return location[0]
}

fun View.absY(): Int
{
    val location = IntArray(2)
    this.getLocationOnScreen(location)
    return location[1]
}

y simplemente obtener X absoluta por view.absX() e Y por view.absY()

Mi función de utilidades para obtener la ubicación vista, devolverá un objeto Point con x value y y value

public static Point getLocationOnScreen(View view){
    int[] location = new int[2];
    view.getLocationOnScreen(location);
    return new Point(location[0], location[1]);
}

Uso

Point viewALocation = getLocationOnScreen(viewA);

Usar este código para encontrar X exacta y cordinates Y:

int[] array = new int[2];
ViewForWhichLocationIsToBeFound.getLocationOnScreen(array);
if (AppConstants.DEBUG)
    Log.d(AppConstants.TAG, "array  X = " + array[0] + ", Y = " + array[1]);
ViewWhichToBeMovedOnFoundLocation.setTranslationX(array[0] + 21);
ViewWhichToBeMovedOnFoundLocation.setTranslationY(array[1] - 165);

He añadido / restado algunos valores para ajustar mi punto de vista. Por favor, estas líneas sólo después entero opinión ha sido inflados.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top