android - 约束布局 : center view on full screen but li

我有一个类似组件实现的工具栏,在所有情况下我都遇到布局问题。它有一个左边的图标、一个标题和一个右边的菜单/按钮。我需要标题在全屏(或至少布局的整个宽度)上居中,但也不与其他组件重叠。因此,标题的宽度必须受到左侧图标和右侧按钮的限制。

我有两个中间解决方案,但似乎找不到将它们结合起来的方法。

一种是将标题置于屏幕中央。这里的问题是标题与右侧按钮重叠(如果足够大,也会与左侧图标重叠......)。这是布局 XML:

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/bottomSheetHeaderIcon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:clickable="true"
        android:focusable="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/bottomSheetHeaderTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textAlignment="center"
        app:layout_constrainedWidth="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="My also very very very very very long title" />

    <TextView
        android:id="@+id/right_action"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="Really long string longer"/>
</androidx.constraintlayout.widget.ConstraintLayout>

另一种是将标题居中放置在左侧图标和右侧按钮之间。现在没有重叠,但标题没有正确居中。由于两侧元素的大小非常不同,标题仅在它们之间居中,这是不好的。这是具有本例约束的相同布局:

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/bottomSheetHeaderIcon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:clickable="true"
        android:focusable="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/bottomSheetHeaderTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textAlignment="center"
        app:layout_constrainedWidth="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@id/right_action"
        app:layout_constraintStart_toEndOf="@+id/bottomSheetHeaderIcon"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="My also very very very very very long title" />

    <TextView
        android:id="@+id/right_action"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:text="Really long string longer"/>
</androidx.constraintlayout.widget.ConstraintLayout>

我正在尝试只使用 XML 布局解决方案,而不必以编程方式检测重叠并更改布局。

如果存在其他布局的解决方案,也可以使用。

问题同题here和 here ,但我希望通过提供更多详细信息,这个解决方案可以获得公认的解决方案。

最佳答案

这是对这个问题的程序化回答,这就是我现在正在使用的,但我真的很想要一个布局解决方案......

我使用第一个布局,以屏幕为中心,因为这是我自定义 View 的一部分,将以下代码添加到构造函数(title 是对 的引用bottomSheetHeaderTitlerightActionright_action,假定左侧图标始终小于右侧操作文本)。

        viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                if (title.width > 0) {
                    if (title.right > rightAction.x) {
                        title.maxWidth = (2.0 * (width / 2.0 - (width - rightAction.x))).toInt()
                    }
                    viewTreeObserver.removeOnGlobalLayoutListener(this)
                }
            }
        })

此代码检测标题是否与正确的操作重叠,如果重叠,则为其添加最大宽度。最大宽度是屏幕中心与右侧操作开始之间距离的两倍。

关于android - 约束布局 : center view on full screen but limit width to not overlap with side views,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63848314/

相关文章:

scala - 在读取 CSV 时,最后一列在 Spark、Scala 中显示为 Null

python - 在使用 pyspark 和预定义的结构模式读取嵌套的 JSON 时,如何将缺失的列

reactjs - 我怎样才能拥有同一个顶级片段容器的多个兄弟实例?

r - 如何使用 R 中的 rcv 和 networkD3 包在 D3 Sankey 图的节点中添加

python - 无法通过 Pip 安装 TensorFlow

linux - 用 n 步旋转文本文件中的行

python - open() 中的整数文件描述符 "0"

firebase - Firebase 推送通知传送缓慢

python-3.x - python 3.8 flask apache 2.4 wsgi 多处理运

python - Anki 网页抓取脚本