【发布时间】:2022-11-19 01:09:54
【问题描述】:
我有一个小部件,无论我对它和其他小部件施加什么限制,包括添加障碍,它始终将自己定位在布局的顶部。
这是一个相当简单的排列,两行,每行两个元素,不是按列对齐。每行中的第一个元素是 TextView 标签,第二个元素是输入 (Spinner)。 第一行上方还有一个单独的 TextView 标题,一直延伸到整个行。根据我对约束布局的理解和以前的经验,这不应该要求行之间有障碍,这是我的初始版本。
这是设计视图,其中所选元素(“Credentials”)应该位于第二行,但实际上出现了以上第一行,在标题 TextView(“PKIX”)之上:
模拟器中的实际结果看起来大同小异。所选的“Credentials”元素是下面 XML 布局中五个元素中的第四个。所有其他元素都在正确的位置。
<?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:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/addsrv_pkix_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@drawable/bottomborder"
android:text="PKIX"
android:textAlignment="center"
android:layout_marginHorizontal="10sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@+id/addsrv_trust_lbl"
/>
<TextView
android:id="@+id/addsrv_trust_lbl"
android:text="Trust"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="10sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/addsrv_trust_spin"
app:layout_constraintTop_toBottomOf="@+id/addsrv_pkix_title"
app:layout_constraintBaseline_toBaselineOf="@+id/addsrv_trust_spin"
app:layout_constraintBottom_toTopOf="@+id/addsrv_cred_lbl"
/>
<Spinner
android:id="@+id/addsrv_trust_spin"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@+id/addsrv_trust_lbl"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/addsrv_pkix_title"
app:layout_constraintBottom_toTopOf="@+id/addsrv_cred_spin"
/>
<TextView
android:id="@+id/addsrv_cred_lbl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:paddingHorizontal="10sp"
android:text="Credentials"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/addsrv_cred_spin"
app:layout_constraintTop_toBottomOf="@+id/addsrv_trust_lbl"
app:layout_constraintBaseline_toBaselineOf="@+id/addsrv_cred_spin"
/>
<Spinner
android:id="@+id/addsrv_cred_spin"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@+id/addsrv_cred_lbl"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/addsrv_trust_spin"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
我很困惑。 addsrv_cred_lbl TextView(“凭证”)是:
- 开始与父对齐。
- 结束与
addsrv_cred_spin微调器对齐,显示位置正确; 这种对齐往复运动以创建水平链。他们也是基线 对齐。 - 顶部与其上方的 TextView 的底部对齐,
addsrv_trust_lbl。 这种排列也是往复的。
还没有底部对齐(还有另一行要走);将它与父级底部对齐没有区别,除非我从同一行底部对齐微调器,在这种情况下,结果会变得越来越糟。
由于这不起作用,我尝试在行之间使用屏障。如果我将它用作“顶部”,将第二行小部件用作约束参照物,则屏障出现在标题上方的顶部,无论使用什么约束将其定位在第一行下方。用作“底部”,引用第一行小部件,第二行链接在它下面(这更符合逻辑),事情要好一些,因为屏障出现在正确的位置——但是“凭证”小部件仍然在顶部。
这个设计视图看起来与之前的设计视图完全相同,只是屏障在第一行下方可见。在 XML 中,我在阅读后添加了 optimizationLevel="none" 可以帮助解决行为不当的障碍(但没有任何区别)。这里还添加了一些样式元素(例如字体大小),我之前为简洁起见删除了这些元素。
<?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:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_optimizationLevel="none"
>
<TextView
android:id="@+id/addsrv_pkix_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@drawable/bottomborder"
android:backgroundTint="@color/tbar"
android:text="PKIX"
android:textAlignment="center"
android:textSize="@dimen/addsrv_bigfont"
android:textColor="@color/titleText"
android:layout_marginHorizontal="10sp"
app:layout_constraintBottom_toTopOf="@+id/addsrv_trust_lbl"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<TextView
android:id="@+id/addsrv_trust_lbl"
android:text="Trust"
android:textSize="@dimen/addsrv_fontsz"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="10sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/addsrv_trust_spin"
app:layout_constraintTop_toBottomOf="@+id/addsrv_pkix_title"
app:layout_constraintBaseline_toBaselineOf="@+id/addsrv_trust_spin"
app:layout_constraintBottom_toTopOf="@+id/addsrv_bar1"
app:layout_constraintHorizontal_chainStyle="packed"
/>
<Spinner
android:id="@+id/addsrv_trust_spin"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@+id/addsrv_trust_lbl"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/addsrv_pkix_title"
app:layout_constraintBottom_toTopOf="@+id/addsrv_bar1"
/>
<androidx.constraintlayout.widget.Barrier
android:id="@+id/addsrv_bar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="addsrv_trust_lbl,addsrv_trust_spin"
app:layout_constraintBottom_toTopOf="@+id/addsrv_cred_lbl"
/>
<TextView
android:id="@+id/addsrv_cred_lbl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="10sp"
android:text="Credentials"
android:textSize="@dimen/addsrv_fontsz"
app:layout_constraintBaseline_toBaselineOf="@+id/addsrv_cred_spin"
app:layout_constraintEnd_toStartOf="@+id/addsrv_cred_spin"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/addsrv_bar1" />
<Spinner
android:id="@+id/addsrv_cred_spin"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@+id/addsrv_cred_lbl"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/addsrv_bar1"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
我是否正确地观察到 addsrv_cred_lbl 上的一些约束被完全忽略了?topToBottom 是否意味着小部件的顶部与另一个小部件的底部对齐?相反,它似乎只是意味着它们将在设计视图中与一条波浪形的、可能弯曲的和盘旋的线连接,并且两个小部件的空间关系是任意的,这样语义逻辑还不如颠倒过来,“top = 底部,底部 = 顶部”,等等。
请注意我不想使用绝对值来定位任何东西.如果让它工作的唯一方法就是那样做,那么即使在这种简单的情况下,约束布局似乎也完全是在浪费时间,我宁愿只是堆叠一些线性布局。
【问题讨论】:
-
我已经删除了基线约束,它看起来不错。您确定 Spinner 有
baseline吗? -
问题似乎是您试图将第二行的 lavbel 与 Spinner 的基线联系起来。我不确定 Spinner 是否有类似的东西。我尝试了第一个例子,只是把它绑在底部而不是基线,它似乎定位正确。
-
是的,这行得通(我还必须删除一个 24sp 的顶部边距,它在某个时候被设计视图偷偷放入“凭据”小部件,在这里也删除了它)。不知道为什么我会被允许创建一个基线约束,如果它实际上没有用的话(为什么显示文本的微调器没有基线?)。另外,即使这样也很棒一一堆边缘虚假警告(“硬编码文本”,“颜色对比度不足”......)提到了这一点。现在也不需要屏障了。呃呃。安薇:谢谢。
标签: android android-constraintlayout