android - 约束布局 : center view on full screen but limit width to not overlap with side views

标签 android android-layout android-constraintlayout

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

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

一种是将标题置于屏幕中央。这里的问题是标题与右侧按钮重叠(如果足够大,也会与左侧图标重叠......)。这是布局 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 布局解决方案,而不必以编程方式检测重叠并更改布局。

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

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

最佳答案

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

我使用第一个布局,以屏幕为中心,因为这是我自定义 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/

相关文章:

android - 如何在android中的string.xml中添加一个有很多段落的长文本

android - 防止 TextView 在 ConstraintLayout 中与另一个重叠?

java - 如何在约束布局中创建容器以便设置背景?

java - 使用 RxJava2 和 Retrofit 在 android 中实现即时搜索时获取 java.io.InterruptedIOException

java - FindItem(R.id.*) 抛出 NullPointerException

Android相对布局定位

android - 对 RecyclerView 中的行布局进行动画更改

javascript - 如何判断我是否在使用 Ionic2 的移动平台上?

android - Camera Error "Can' t Connect to the Camera”或者在某些手机中出现错误 "Camera is using by another app"

android - RecyclerView 显示为灰色框,其名称位于中心。对于已实现的音频可视化器 View 也是如此