web-dev-qa-db-ja.com

ConstraintLayout内のWrap_contentビューが画面外に広がる

私はConstraintLayoutを使って簡単なチャットバブルを実装しようとしています。これが私が達成しようとしていることです。

enter image description hereenter image description here

しかし、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>

これは以下のようにレンダリングされます。

enter image description here

私はcom.Android.support.constraint:constraint-layout:1.0.0-beta4を使っています。

私は何か悪いことをしていますか?それはバグなのか、それとも単なる直感に反する行動なのでしょうか。 ConstraintLayoutを使用して適切な動作を実現できますか(他のレイアウトを使用できることはわかっています。特にConstrainLayoutについて質問しています)。

91
Marcin Jedynak

期限切れ: より良い答えを参照

いいえ、今日のようにConstraintLayoutではあなたが望むことはできません(1.0 beta 4):

  • wrap_contentはウィジェットにそれ自体を測定するように要求するだけですが、最終的な制約に対してその拡張を制限することはありません
  • match_constraints(0dp)ウィジェットのサイズを制約条件に対して制限しますが、wrap_contentがもっと小さい場合でもそれらに一致します(最初の例)これはあなたが望むものではありません。

だから今、あなたはその特定のケースのために運が悪いです: - /

今、私たちはこの正確なシナリオに対処するためにmatch_constraintsに機能を追加することを考えています(サイズが制約を超えて終わらない限りwrap_contentとして振る舞う)。

私はこの新機能が1.0リリースの前にそれを作ることを約束することはできません。

編集:属性app:layout_constraintWidth_default="wrap"(幅を0dpに設定)を使用して1.0でこの機能を追加しました。設定すると、ウィジェットはwrap_contentを使用した場合と同じサイズになりますが、制約によって制限されます(つまり、それを超えて拡張することはありません)。

188
Nicolas Roard

更新(ConstraintLayout 1.1。+)

幅をapp:layout_constrainedWidth="true"に設定してwrap_contentを使用する

以前(非推奨):

幅がapp:layout_constraintWidth_default="wrap"に設定された0dp

146
Silvia H

はい、 Nikolas Roard の回答で述べたように、app:layout_constraintWidth_default="wrap"を追加してwidthを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>

その結果、次のようになります。

enter image description here

18
Eugene Brusov

他の答えがすでに言ったように、ConstraintLayout 1.0以来それを達成することは可能ですが、最新のリリース(1.1.x)の時点でそれらはあなたがそれをする方法を変えました。

ConstraintLayout 1.1のリリース以降、古いapp:layout_constraintWidth_default="wrap"およびapp:layout_constraintHeight_default="wrap"属性は廃止予定になりました

wrap_contentの振る舞いを提供したいが、それでもあなたのビューに制約を強制したい場合は、ドキュメントの のように、その幅や高さをwrap_contentapp:layout_constrainedWidth=”true|false”属性と組み合わせてapp:layout_constrainedHeight=”true|false”に設定するべきです。

WRAP_CONTENT:制約の強制(1.1で追加)1.1より前のバージョンでは、次元がWRAP_CONTENTに設定されている場合、リテラル次元として扱われます - 意味制約は結果の寸法を制限しません。一般的にはこれで十分です(しかも高速です)が、場合によってはWRAP_CONTENTを使用しながら、結果のディメンションを制限するために制約を強制し続けることをお勧めします。その場合は、対応する属性の1つを追加できます。

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

最新のリリースに関しては、私がこれに答えるまでに、 ConstraintLayoutはバージョン1.1.2 にあります。

8
Mauker

Deprecation of app:layout_constraintWidth_default text and its alternative

@ nicolas-roardによるapp:layout_constraintWidth_default="wrap"およびAndroid:layout_width="0dp"の回答は現在非推奨です。

app:layout_constrainedWidth="true"Android:layout_width="wrap_content"を使ってください。

廃止予定の理由、私は知りません。しかし、ConstraintLayoutのソースコードにおける権利

1
Bolaji