ConstraintLayout:全屏显示中心视图,但宽度限制不能与侧视图重叠 [英] ConstraintLayout: center view on full screen but limit width to not overlap with side views

查看:68
本文介绍了ConstraintLayout:全屏显示中心视图,但宽度限制不能与侧视图重叠的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类似于组件实现的工具栏,在所有情况下我都遇到布局问题.它有一个左图标,一个标题和一个右菜单/按钮.我需要标题以全屏(或至少布局的整个宽度)为中心,并且不与其他组件重叠.因此,标题的宽度必须受左图标和右按钮的约束.

我有两种中间解决方案,但似乎找不到结合它们的方法.

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

 < androidx.constraintlayout.widget.ConstraintLayoutxmlns:android ="http://schemas.android.com/apk/res/android"xmlns:app =" http://schemas.android.com/apk/res-autoxmlns:tools ="http://schemas.android.com/tools"android:layout_width =" match_parent"android:layout_height =" wrap_content">< ImageViewandroid: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"/>< TextViewandroid: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 =我也非常非常非常长的标题"/>< TextViewandroid: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"工具:text =真正更长的字符串更长"/></androidx.constraintlayout.widget.ConstraintLayout> 

另一种方法是将标题置于左图标和右按钮之间.现在没有重叠,但是标题没有正确居中.由于这两个侧边元素的大小差异很大,因此标题仅位于它们之间的中间位置,这是不好的.这是这种情况下具有相同约束的布局:

 < androidx.constraintlayout.widget.ConstraintLayoutxmlns:android ="http://schemas.android.com/apk/res/android"xmlns:app =" http://schemas.android.com/apk/res-autoxmlns:tools ="http://schemas.android.com/tools"android:layout_width =" match_parent"android:layout_height =" wrap_content">< ImageViewandroid: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"/>< TextViewandroid: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 =我也非常非常非常长的标题"/>< TextViewandroid: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"工具:text =真正更长的字符串更长"/></androidx.constraintlayout.widget.ConstraintLayout> 

我试图摆脱XML布局解决方案,而不必以编程方式检测重叠并更改布局.

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

问题与问题此处,但我希望通过提供更多详细信息,可以使该解决方案得到接受.

解决方案

以下是此问题的程序化答案,这就是我现在正在使用的内容,但我真的很希望使用布局解决方案...

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

  viewTreeObserver.addOnGlobalLayoutListener(object:ViewTreeObserver.OnGlobalLayoutListener {覆盖fun onGlobalLayout(){如果(title.width> 0){如果(title.right> rightAction.x){title.maxWidth =(2.0 *(宽度/2.0-(宽度-rightAction.x))).toInt()}viewTreeObserver.removeOnGlobalLayoutListener(this)}}}) 

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

I have a toolbar like component implementation, that I'm having trouble with the layout in all situations. It has a left icon, a title and a right menu/button. I need the title to be centered on the full screen (or at least the full width of the layout) but also to not overlap with the other components. So the width of the title would have to be constrained by the left icon and the right button.

I have two intermediary solutions but can't seem to find a way to combine them.

One is to center the title on the screen. The problem here is that the title overlaps with the right button (and would overlap with the left icon too, if large enough ...). Here is the layout 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>

The other is to center the title between the left icon and the right button. Now there is no overlap, but the title is not centered correctly. Since the two side elements have very different sizes, the title is only centered between them, which is no good. Here is the same layout with the constraints for this case:

<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>

I'm trying to get away with just a XML layout solution, without having to do programmatically detect overlaps and change the layout.

Solutions with other layouts would also work, if they exist.

The problem is the same as the questions here and here, but I'm hoping that by giving more detail, this one gets an accepted solution.

解决方案

Here is a programatic answer to this question, that is what I'm using for now, but I'd really like a layout solution ...

I use the first layout, centered on the screen, and, as this is part of a custom view for me, add the following code to the constructor (title is a reference to bottomSheetHeaderTitle and rightAction is right_action, the left icon is assumed to always be smaller than the right action text).

        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)
                }
            }
        })

This code detects if the title overlaps the right action, and, if it does, adds a max width to it. The max width is the double of the distance between the center of the screen and the beginning of the right action.

这篇关于ConstraintLayout:全屏显示中心视图,但宽度限制不能与侧视图重叠的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆