gpt4 book ai didi

java - 在 GUI 构建器中找到的对齐准则/对齐算法

转载 作者:行者123 更新时间:2023-11-30 00:45:36 24 4
gpt4 key购买 nike

我尝试实现一种类似于许多 GUI 构建器的行为:如果当前拖动的组件几乎与另一个组件处于水平或垂直线上,则它们应该与另一个组件对齐。我当前的方法是遍历所有放置的组件并检查四个边缘中的任何一个是否(几乎)与拖动组件的边缘对齐:

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

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

但这似乎效率低下,因为它是在 onTouch 中调用的,所以这个循环运行得非常频繁。有更好的方法吗?欢迎一般或 Java 回答。

最佳答案

一种更有效的方法是将遍历所有 View 的 O(n) 循环减少到 O(log n) 搜索最近的边缘一些排序的表示形式,如 TreeSet TreeMap , 这是 balanced binary search trees .当然,这需要您为 leftEdge 中的每一个存储四个单独的排序表示。 , rightEdge , topEdge , 和 bottomEdge .

一个简单的例子是(仅显示 leftEdge ,其他类似):

val viewsByLeftEdge = TreeMap<Int, View>()

要将 View 添加到 map 中,只需使用:

viewsByLeftEdge[view.leftEdge()] = view

(请注意,如果多个 View 的左边缘值相同,则只会将最后一个存储在该 map 中)

之后,您可以找到给定 left 最近的左边缘,而不是遍历所有 View 。坐标:

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

在这里, .floorKey(x) 返回 map 中小于或等于 x 的最高边坐标, 或 null如果没有这样的坐标。同样, .ceilingKey(x) 返回 map 中大于 x 的最低坐标, 或 null .

这需要 O(log n) 时间,并且比遍历任何大量 View 的所有 View 要快。如果您不需要通过边缘获取 View ,请通过替换 TreeMap<Int, View> 来简化代码与 TreeSet<Int> (然后函数是 floor(x)ceiling(x)

将 map 放置在代码中由您决定,用您的 View 填充它们s 并为四个边缘组合更适合您的代码设计的函数。

关于java - 在 GUI 构建器中找到的对齐准则/对齐算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41849830/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com