trabajar plano hacer ejercicios dibujar definicion coordenadas con como comando cartesiano absolutas android android-tablelayout

android - plano - coordenadas en autocad 2017



Cómo obtener las coordenadas absolutas de una vista (7)

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 elemento primario de la vista, por lo que me dan 0 . ¿Cuál es la forma apropiada de hacer esto?

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

Edición: Este es el código que utilicé para intentar obtener el tamaño del contenedor de retención, 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 he intentado, 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 fue agregado después de que se realiza toda la inicialización. La imagen se ha dividido en una matriz de ImageViews (la celda [] matriz) contenida dentro de un TableLayout . Células [0] es el ImageView superior izquierdo, y seleccioné celdas [4] ya que está en algún lugar en el medio y definitivamente no debería tener coordenadas de (0,0).

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

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


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

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

Utilizando

Point viewALocation = getLocationOnScreen(viewA);


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

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

Notas

  • Reemplazar View.getLocationOnScreen() con getLocationInWindow() debería dar los mismos resultados en la mayoría de los casos (vea esta respuesta ). Sin embargo, si se encuentra en una ventana más pequeña, como un diálogo o un teclado personalizado, entonces deberá elegir el que mejor se adapte a sus necesidades.
  • Obtendrá (0,0) si llama a este método en onCreate porque la vista aún no se ha diseñado. Puede usar un ViewTreeObserver para escuchar cuando se realiza el diseño y 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


Siguiendo el comentario de Romain Guy, así es como lo arreglé. Esperemos que ayude a cualquier otra persona que también haya tenido este problema.

De hecho, estaba tratando de obtener las posiciones de las vistas antes de que se presentaran en la pantalla, pero no era del todo obvio que eso estaba sucediendo. Esas líneas se colocaron después de que se ejecutó el código de iniciación, así que asumí que todo estaba listo. Sin embargo, este código todavía estaba en onCreate (); al experimentar con Thread.sleep () descubrí que el diseño no se finaliza realmente hasta que después de que onCreate () haya terminado de ejecutarse hasta onResume (). Así que, de hecho, el código intentaba ejecutarse antes de que el diseño hubiera terminado de colocarse en la pantalla. Al agregar el código a un OnClickListener (o algún otro Oyente), se obtuvieron los valores correctos porque solo se podía disparar una vez que el diseño había terminado.

La siguiente línea fue sugerida como una edición de la comunidad:

por favor use onWindowfocuschanged(boolean hasFocus)


Usar un oyente de diseño global siempre me ha funcionado bien. Tiene la ventaja de poder volver a medir las cosas si se modifica el diseño, por ejemplo, si se configura algo en View.GONE o se agregan / eliminan vistas secundarias.

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); }


Use este código para encontrar las coordenadas X e Y exactas:

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 vista. Por favor, haga estas líneas solo después de que se haya inflado toda la vista.