如何相对于彼此定位 2 个视图?
Posted
技术标签:
【中文标题】如何相对于彼此定位 2 个视图?【英文标题】:How to position 2 Views relative to each other? 【发布时间】:2019-08-31 11:09:04 【问题描述】:我想相对于彼此定位 2 个视图,但不只是相对于顶部、底部、左侧或右侧,而是以 成比例的方式。让我解释。以下是4种定位场景:
其中,2) 和 4) 很容易实现,并且具有由标准布局容器(例如 RelativeLayout、ConstraintLayout)提供的内置支持,但我当前的任务需要场景 1)/3) 中描述的定位
此问题的一个简单解决方案是为两个视图与父级设置不同的左/上边距,但这意味着如果需要将两个视图一起放置到其他位置,则所有边距都必须更改。
相反,我希望在这两个视图之间进行某种相对定位安排,以使它们保持相对“正确”的距离,无论它们作为一个单元放置在父级中的什么位置。
我怎样才能达到同样的效果?一个有效的解决方案(具有扁平的层次结构,没有视图黑客)将不胜感激。
【问题讨论】:
您希望它们在运行时更改吗? @AvinashJoshi :不。我想将它们定位在 XML 中一次 【参考方案1】:将不胜感激一个有效的解决方案(具有扁平的层次结构,没有视图黑客)。,您可以使用 ConstraintLayout 和 guidelines。
指南具有app:layout_constraintGuide_percent
属性,使其能够响应屏幕尺寸。
您可以在为按钮添加app:layout_constraintWidth_percent
和app:layout_constraintHeight_percent
属性时使用它(不是强制性的,您可以将视图限制在指南中,但我相信它更简单)。
这是您想要的具有扁平层次结构的布局示例:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_
android:layout_>
<Button
android:id="@+id/button2"
android:layout_
android:layout_
android:text="Button"
app:layout_constraintHeight_percent=".1"
app:layout_constraintStart_toStartOf="@+id/guideline"
app:layout_constraintTop_toTopOf="@+id/guideline2"
app:layout_constraintWidth_percent=".3" />
<Button
android:id="@+id/button"
android:layout_
android:layout_
android:text="Button"
app:layout_constraintBottom_toTopOf="@+id/guideline4"
app:layout_constraintEnd_toStartOf="@+id/guideline"
app:layout_constraintHeight_percent=".1"
app:layout_constraintWidth_percent=".3" />
<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_
android:layout_
android:orientation="vertical"
app:layout_constraintGuide_percent=".5" />
<android.support.constraint.Guideline
android:id="@+id/guideline2"
android:layout_
android:layout_
android:orientation="horizontal"
app:layout_constraintGuide_percent=".4" />
<android.support.constraint.Guideline
android:id="@+id/guideline4"
android:layout_
android:layout_
android:orientation="horizontal"
app:layout_constraintGuide_percent=".45" />
</android.support.constraint.ConstraintLayout>
看起来像这样(我从预览中添加屏幕截图以便更好地理解指南):
这只是一个示例,但使用这些工具,您可以根据需要创建布局。
一些额外的信息
我的解决方案在我的视图上不包含任何固定大小的尺寸,这将使布局具有响应性(无需为每个屏幕尺寸构建布局)
您可能还会找到与您的问题相关的ConstraintLayout: Circular Positioning,但我认为这对您来说并不是最好的选择。
【讨论】:
据我了解,在您的解决方案中,如果我需要将 2 个视图作为一个单元在任何方向对角移动,我将不得不移动所有指南。在移动所有准则时,我还必须确保准则之间的相对距离保持不变。第三,准则到新位置的计算映射会变得有点复杂。 据我了解,在您的解决方案中,如果我需要将 2 个视图作为一个单元在任何方向对角移动,我将不得不移动所有指南,您可以放置它在片段内并在布局中移动您的片段。但也许考虑检查我的回答中提到的圆形定位,在看到您的评论后,我相信它可能适合您的用例。 或者,我害怕的是……有一个自定义的ViewGroup
,它支持具有 2 个视图的合成,并具有有助于指定相对位置尺寸的自定义属性。如果任何视图的大小发生变化,layout()/invalidate() 也会重新计算父视图的相对定位。相当多的工作!
工作量很大,因为你想要一些非常具体的东西,据我所知,你可以使用指南或使用ConstraintLayout: Circular Positioning
,如果你能找到更好的东西,请在这里评论我我也可以学。【参考方案2】:
是的,可以在第 3 点的 XML 代码下方使用约束布局签出。(如果您有疑问,将执行相同的第 2 点,让我知道)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_
android:layout_>
<androidx.appcompat.widget.AppCompatButton
android:layout_
android:layout_
android:id="@+id/buttonA"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="Add"
android:layout_marginTop="15dp"
/>
<androidx.appcompat.widget.AppCompatButton
android:layout_
android:layout_
app:layout_constraintStart_toEndOf="@id/buttonA"
app:layout_constraintEnd_toEndOf="@id/buttonA"
app:layout_constraintTop_toBottomOf="@id/buttonA"
android:text="Add"
/>
</androidx.constraintlayout.widget.ConstraintLayout>`
请查看下面的代码,这是一种补丁,但工作正常。在这里我们可以将大块相对于小块。因为我们使用了约束,所以无论你放在哪里都会粘在一起。如果我做错了什么,请告诉我。
这里我们使用一个 dummyView 和 app:layout_constraintHorizontal_bias="0.1"
使其相对值从 0 变为 1,例如 1 表示 100% 表示从左到小块 smae 方式 0.5 表示从小块开始到左的 50%。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_
android:layout_>
<androidx.appcompat.widget.AppCompatButton
android:layout_
android:layout_
android:id="@+id/buttonA"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:text="Add"
android:layout_marginTop="15dp"
/>
<TextView android:layout_
android:layout_
android:id="@+id/dummyView"
app:layout_constraintTop_toBottomOf="@id/buttonA"
app:layout_constraintStart_toStartOf="@id/buttonA"
app:layout_constraintEnd_toEndOf="@id/buttonA"
app:layout_constraintHorizontal_bias="0.1"/>
<androidx.appcompat.widget.AppCompatButton
android:layout_
android:layout_
app:layout_constraintTop_toBottomOf="@id/buttonA"
app:layout_constraintStart_toEndOf="@id/dummyView"
android:text="Add"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
【讨论】:
不,这仅适用于视图需要相对于另一个视图的宽度/高度中间定位的特殊情况。不适用于一般定位! 好的,我已经更新了我的答案,如果有问题请查看并告诉我。以上是关于如何相对于彼此定位 2 个视图?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用 ConstraintLayout 中的边距属性的情况下相对于屏幕宽度设置 2 个视图之间的空间
使用 iOS 6 Auto Layout 相对于 superview 的大小定位视图