ConstraintLayout内的Wrap_content视图延伸到屏幕外。

185 人关注

我想用 ConstraintLayout 来实现一个简单的聊天气泡。这就是我想实现的目标。

然而, wrap_content 并没有达到我想要的效果。它尊重页边距,但却在视图范围之外扩展。下面是我的布局。

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <TextView
        android:id="@+id/chat_message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="16dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintHorizontal_bias="0"
        tools:background="@drawable/chat_message_bubble"
        tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sodales accumsan tortor at bibendum."
        android:layout_marginStart="64dp"
        android:layout_marginLeft="64dp"
        android:layout_marginEnd="32dp"
        android:layout_marginRight="32dp"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp" />
</android.support.constraint.ConstraintLayout>

这句话解释如下。

I am using com.android.support.constraint:constraint-layout:1.0.0-beta4.

我是不是做错了什么?这是一个错误还是一个不直观的行为?我可以使用ConstraintLayout实现适当的行为吗(我知道我可以使用其他布局,我特别问的是ConstrainLayout)。

5 个评论
你能把文本视图和它的父约束布局一起贴出来吗? 你知道,父布局的属性对子布局有很大影响
顺便说一下,在你的情况下,我想水平偏置是罪魁祸首。
横向偏置是必要的,否则如果气泡居中。如果没有从右到右的布局,右边的空白就不会被考虑到,这不是我们想要的。我试着按照你的建议去掉它们,但没有用。
问题肯定是水平偏置0。我将检查可能的解决方案并尽快发布,因为我也在处理类似的约束性布局问题。
@nmu的聊天气泡来自 tools:background="@drawable/chat_message_bubble" 。要实现它,你必须在drawable文件夹中创建chat_message_bubble.xml文件,然后添加此代码。 【替换代码1
android
android-layout
android-constraintlayout
Marcin Jedynak
Marcin Jedynak
发布于 2016-11-29
7 个回答
Silvia H
Silvia H
发布于 2017-10-04
已采纳
0 人赞同

Updated (ConstraintLayout 1.1.+)

Use app:layout_constrainedWidth="true" with android:layout_width="wrap_content"

Previously (deprecated):

app:layout_constraintWidth_default="wrap" with android:layout_width="0dp"

是的,我相信从ConstraintLayout 1.1.0 beta 2开始。 androidstudio.googleblog.com/2017/10/...
爱上Stackoverflow!感谢这对我的帮助!保持包裹的内容,但永远不要超出约束的范围。#TIL
多么好的答案,我不知道有这个东西存在谢谢你,在玩了2个小时的替代方案后,这个方法很有效!
Alex
你让我的日子好过了
Nicolas Roard
Nicolas Roard
发布于 2017-10-04
0 人赞同

Outdated: See better answer

不,你不能用现在的ConstraintLayout(1.0 beta 4)做你想要的事情。

  • wrap_content only asks the widget to measure itself, but won't limit its expansion against eventual constraints
  • match_constraints (0dp) will limit the size of the widget against the constraints... but will match them even if wrap_content would have been smaller (your first example), which isn't what you want either.
  • 因此,现在,对于这个特殊的案例,你已经不走运了 :-/。

    现在......我们正在考虑为 match_constraints 增加额外的功能,以处理这种确切的情况(表现为 wrap_content ,除非尺寸最终超过了约束)。

    不过我不能保证这个新功能会在1.0版本之前实现。

    Edit : 我们确实在1.0中用属性 app:layout_constraintWidth_default="wrap" 添加了这个功能(宽度设置为0dp)。如果设置了这个属性,小部件将拥有与使用wrap_content相同的尺寸,但会受到限制(即它不会扩展到它们之外)。

    现在,这些标签被废弃了,取而代之的是使用 layout_width="WRAP_CONTENT" 和 layout_constrainedWidth="true"。

    这对我来说是个超级问题。我现在不能用TextView和复合绘图仪,因为如果我把它设置为 match_constraints ,复合绘图仪就会在最右边,即使有很短的文本。
    @NicolasRoard:你能帮我解决约束布局的问题吗,我在上半部分有一张图片,准则是0.4,下面是内容,但当我把约束布局设置为wrap_content时,它只选择了0.4的屏幕(下面一半的文本视图不可见),我也用了 app:layout_constraintWidth_default="wrap" ,以及库的V1.0.2,但没有帮助。
    app:layout_constraintWidth_default="wrap" width as 0dp does it nicely!
    这在文件/说明中应该是明确的。
    Should the Edit 动有更大的突出地位?在原来的基础上,有点迷失了。谢谢你的回答。谢谢 @NicolasRoard .
    Eugene Brusov
    Eugene Brusov
    发布于 2017-10-04
    0 人赞同

    是的,就像回答中提到的 Nicolas Roard 你应该添加 app:layout_constraintWidth_default="wrap" 并设置宽度为0dp。而为了使你的泡沫正确对齐,你应该将 layout_constraintHorizontal_bias 设置为1.0。

    这里是最终的源代码。

    <android.support.constraint.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/chat_message"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:padding="16dp"
            android:layout_marginTop="8dp"
            android:layout_marginStart="64dp"
            android:layout_marginEnd="8dp"
            android:layout_marginBottom="8dp"
            app:layout_constraintHorizontal_bias="1.0"
            app:layout_constraintWidth_default="wrap"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            android:background="@drawable/chat_message_bubble"
            android:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sodales accumsan tortor at bibendum." />
    </android.support.constraint.ConstraintLayout>
    

    结果是,它看起来像。

    我认为这是因为OP想要左边的小气泡,而你的是右边,这就改变了要求。
    这里的重要部分是 app:layout_constraintHorizontal_bias="1.0"
    是的,如果你想让起点而不是终点对齐,使用app:layout_constraintHorizontal_bias="0"(注意:浮点不需要)。
    Mauker
    Mauker
    发布于 2017-10-04
    0 人赞同

    就像其他答案已经说过的,从ConstraintLayout 1.0开始就可以实现,但从最新的版本(1.1.x)开始,他们已经改变了你的方法。

    自从ConstraintLayout 1.1发布后,旧的 app:layout_constraintWidth_default="wrap" app:layout_constraintHeight_default="wrap" 属性 现在已被弃用 .

    如果你想提供一个 wrap_content 的行为,但仍然对你的视图执行约束。你应该将其宽度和/或高度设置为 wrap_content ,并结合 app:layout_constrainedWidth=”true|false” 和/或 app:layout_constrainedHeight=”true|false” 属性,如前所述 on the docs :

    WRAP_CONTENT : 强化约束 (在1.1中添加) 如果一个维度被 设置为WRAP_CONTENT,在1.1之前的版本中,它们将被视为一个 字面维度 -- 也就是说,约束条件不会限制结果的 维度。虽然在一般情况下这已经足够了(而且速度更快),但在某些情况下 在某些情况下,你可能希望使用WRAP_CONTENT,但同时又要强制执行 来限制结果的维度。在这种情况下,你可以 添加一个相应的属性。

    app:layout_constrainedWidth="true|false" app:layout_constrainedHeight="true|false"

    至于最新的版本,在我回答这个问题的时候。 ConstraintLayout的版本是1.1.2。 .

    Bolaji
    Bolaji
    发布于 2017-10-04
    0 人赞同

    @nicolas-roard对 app:layout_constraintWidth_default="wrap" android:layout_width="0dp" 的回答是现在 已删除 .

    Go ahead and use app:layout_constrainedWidth="true" and android:layout_width="wrap_content" .

    废弃的原因,我不知道。但它就在ConstraintLayout的源代码中

    jsHate
    jsHate
    发布于 2017-10-04
    0 人赞同

    I use this one

    app:layout_constraintEnd_toEndOf="parent"
        
    Alex
    这怎么能回答OP的问题? 这怎么能包住内容?
    Mehul
    Mehul
    发布于 2017-10-04
    0 人赞同

    你应该更换

    android:layout_width="wrap_content"
    
    android:layout_width="match_parent"
    

    然后相应地调整padding和margin。 我已经更新了你的代码。

    <android.support.constraint.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">
    <TextView
        android:id="@+id/chat_message"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="10dp"
        android:layout_marginLeft="60dp"
        android:layout_marginRight="10dp"
        android:layout_marginStart="60dp"
        android:layout_marginTop="8dp"
        android:padding="16dp"
        app:layout_constraintTop_toTopOf="parent"
        tools:background="#c9c7c7"
        tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sodales accumsan tortor at bibendum." />