如何在 ConstraintLayout 中设置视图的绝对位置

Posted

技术标签:

【中文标题】如何在 ConstraintLayout 中设置视图的绝对位置【英文标题】:How to set an absolute position of a view in a ConstraintLayout 【发布时间】:2020-04-16 23:57:52 【问题描述】:

当我使用getLocationOnScreengetLocationInWindow 时,我得到了视图的绝对坐标。令我惊讶的是,视图的 y 坐标考虑了手机的状态栏,这意味着如果视图位于屏幕顶部,它的 y 不会设置为 0。

profilePic1.getLocationOnScreen(imagePosition1.coor)

另一方面,使用view.xview.y 设置视图的位置不是绝对的,而是相对于布局,这意味着:

profilePic1.y = imagePosition1.coor[1]

将图像放置在完全不同的位置,因为它会将状态栏的高度添加到新位置。

我的问题是:当视图位于 ConstraintLayout 内时,是否可以绝对设置视图的坐标?我确实找到了关于涉及相对布局的讨论。 另一种选择:是否可以获取布局的相对坐标,而不是绝对坐标(如 getLocationOnScreen 所做的那样)?

我的问题是我在布局中获取了视图的位置,无法使用这些信息重新定位视图

【问题讨论】:

【参考方案1】:

哦,这是我的错,答案很简单,可以使用:

view.top
view.left

获取布局内的相对位置。我不想删除这个问题,也许其他人可以从中受益,显示绝对屏幕位置和布局内的相对位置之间的差异

【讨论】:

【参考方案2】:

是否可以绝对设置视图的坐标, 而视图在 ConstraintLayout 内?

ConstraintLayout 中定位视图应该使用约束来完成;因为layout_editor_absolutex|y 仅用于设计目的。

但是这里有几种方法可以将视图定位在ConstraintLayout 中的绝对位置:

将视图的topMargin & leftMargin 设置为绝对位置
val view = findViewById<...>

val params = view.layoutParams as ConstraintLayout.LayoutParams
params.leftMargin = x // absolute x position
params.topMargin = y // absolute y position
view.requestLayout()
创建水平和垂直准线,并将它们的边缘分别设置为y、x绝对位置;然后约束视图定位到指南。
val view = findViewById<...>

// Create a horizontal & vertical guidelines and add them to the constraintLayout.
val verticalGL = getGuideline(this, ConstraintLayout.LayoutParams.VERTICAL)
val horizontalGL = getGuideline(this, ConstraintLayout.LayoutParams.HORIZONTAL)
constraintLayout.addView(verticalGL)
constraintLayout.addView(horizontalGL)

// Set the position of the guidelines.
verticalGL.setGuidelineBegin(x) // absolute x position
horizontalGL.setGuidelineBegin(y) // absolute y position

val set = ConstraintSet()
// Clone the layout's ConstraintSet.
set.clone(constraintLayout)
// Constraint the button to the guideline and apply to the ConstraintSet.
set.connect(view.id, ConstraintSet.START, verticalGL.id, ConstraintSet.START)
set.connect(view.id, ConstraintSet.TOP, horizontalGL.id, ConstraintSet.TOP)
set.applyTo(constraintLayout)


private fun getGuideline(context: Context, orientation: Int): Guideline 
    val guideline = Guideline(context)
    guideline.id = Guideline.generateViewId()
    val lp = ConstraintLayout.LayoutParams(
        ConstraintLayout.LayoutParams.WRAP_CONTENT,
        ConstraintLayout.LayoutParams.WRAP_CONTENT
    )
    lp.orientation = orientation
    guideline.layoutParams = lp
    return guideline


【讨论】:

我假设您要定位的视图没有限制

以上是关于如何在 ConstraintLayout 中设置视图的绝对位置的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ConstraintLayout 中设置视图的绝对位置

在 ConstraintLayout 中滚动 RecyclerView 时如何折叠工具栏?

ConstraintLayout:如何展平此布局?

如何使 ConstraintLayout 使用百分比值?

Android:如何使用 ConstraintLayout 在另一个小部件上显示一个小部件?

如何连续对齐 2 个图像视图?