Algoritmo de alignment / alignment de alignment encontrado en constructores de GUI

Intento implementar un comportamiento que sea similar a muchos constructores de GUI: los componentes actualmente arrastrados deben ajustarse en alignment con otro componente si están casi en una línea horizontal o vertical con él. Mi enfoque actual es iterar sobre todos los componentes colocados y verificar si alguno de los cuatro bordes está (casi) alineado con un borde del componente arrastrado:

for (v in rootView.relativeLayout.children()) { // x val left = event.rawX - dXInit val right = event.rawX - dXInit + view.width val leftEdgeRange = (v.leftEdge() - 50 .. v.leftEdge() + 50) val rightEdgeRange = (v.rightEdge() - 50 .. v.rightEdge() + 50) when (left) { in leftEdgeRange -> x = v.leftEdge() in rightEdgeRange -> x = v.rightEdge() } when (right) { in leftEdgeRange -> x = v.leftEdge() - view.width in rightEdgeRange -> x = v.rightEdge() - view.width } // y val top = event.rawY - dYInit val bottom = event.rawY - dYInit + view.height val topEdgeRange = (v.topEdge() - 50 .. v.topEdge() + 50) val bottomEdgeRange = (v.bottomEdge() - 50 .. v.bottomEdge() + 50) when (top) { in topEdgeRange -> y = v.topEdge() in bottomEdgeRange -> y = v.bottomEdge() } when (bottom) { in topEdgeRange -> y = v.topEdge() - view.height in bottomEdgeRange -> y = v.bottomEdge() - view.height } } 

con

 fun View.topEdge() = y fun View.bottomEdge() = y + height fun View.leftEdge() = x fun View.rightEdge() = x + width 

Pero esto parece ineficiente porque se llama onTouch , por lo que este ciclo se ejecuta con bastante frecuencia. ¿Hay un mejor enfoque? Las respuestas generales o de Java son bienvenidas.

Un enfoque más eficiente sería networkingucir el bucle O (n) que itera sobre todas las vistas a una búsqueda O (log n) para el borde más cercano en una representación orderada como TreeSet o TreeMap , que son treees de búsqueda binarys equilibrados . Esto, por supuesto, requiere que almacene cuatro representaciones orderadas separadas para cada uno de los leftEdge : rightEdge , topEdge , bottomEdge y bottomEdge .

Un ejemplo simple sería (mostrando solo leftEdge , los otros son similares):

 val viewsByLeftEdge = TreeMap<Int, View>() 

Para agregar una vista al map, simplemente use:

 viewsByLeftEdge[view.leftEdge()] = view 

(Tenga en count que si varias vistas tienen el mismo valor de borde izquierdo, solo el último se almacenará en este map)

Y después de eso, en lugar de iterar sobre todas las vistas, puede encontrar el borde izquierdo más cercano a una determinada coorderada left :

 val floorL = viewsByLeftEdge.floorKey(left) val ceilingL = viewsByLeftEdge.ceilingKey(left) val nearestL = when { floorL == null -> ceilingL ceilingL == null -> floorL ceilingL - left < left - floorL -> ceilingL else -> floorL } if (nearestL in left - 50 .. left + 50) x = nearestL 

Aquí, .floorKey(x) devuelve la coorderada de borde más alta en el map que es menor o igual a x , o null si no hay tal coorderada. De forma similar, .ceilingKey(x) devuelve la coorderada más baja en el map que es mayor que x , o null .

Esto toma el time O (log n) y será más rápido que iterar sobre todas las vistas para cualquier cantidad significativa de vistas. Si no necesita get la vista por su borde, simplifique el código reemplazando TreeMap<Int, View> con TreeSet<Int> (las funciones son floor(x) y ceiling(x) .

Depende de usted colocar los maps en su código, llenarlos con sus View y componer las funciones para los cuatro bordes que se ajusten mejor al layout de su código.

  • El atributo se borra después de la initialization - kotlin
  • kotlin check tipo types incompatibles
  • extracción de resources de string para kotlin en android studio?
  • El filtrado de la entidad Hibernate con @Filter no filtra
  • Para una function de Kotlin utilizada como expresión, ¿hay una forma concisa de operar y devolver un valor?
  • Kotlin: Interfaz ... no tiene constructores
  • Cómo "anteponer" un Char a una cadena en Kotlin
  • Tipo de valor de par universal para extras de bash
  • Usando la variable de otro file Kotlin
  • No se puede comstackr una function de extensión con parámetro de tipo reificado en Kotlin
  • ¿Cómo dividir una cadena con un set de delimitadores y encontrar qué delimitador era? Kotlin