ConstraintLayout 1.1.0
を使用している場合、使用する正しいプロパティは、古いapp:layout_constrainedWidth="true"
(および対応する高さ)の代わりにapp:layout_constraintWidth_default="wrap"
です。更新された回答を参照してください。
ConstraintLayout 1.0.0
stable(またはそれ以上)(現時点では1.0.2)を使用している場合、レイアウトをネストする必要のない、よりシンプルなソリューションについては、更新された回答を参照してください。
2016年11月3日にリリースされたConstraintLayouts-Beta3
の使用。( source )
私は次のことをしようとしています:
| |
|<-[TextView]<->[ImageView] -----------> |
| |
私はそのようなレイアウトで達成しました:
<TextView
Android:id="@+id/textView"
Android:layout_height="wrap_content"
Android:layout_width="wrap_content"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toLeftOf="@+id/caret"
app:layout_constraintHorizontal_bias="0.0"
Android:text="Some Text"
Android:textAlignment="viewStart"
Android:gravity="start" />
<ImageView
Android:id="@+id/caret"
Android:layout_width="wrap_content"
Android:layout_height="8dp"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintLeft_toRightOf="@+id/textView"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/textView"
app:layout_constraintBottom_toBottomOf="@+id/textView"
app:layout_constraintHorizontal_bias="0.0"
Android:contentDescription=""
app:srcCompat="@drawable/ic_selection"
Android:layout_marginStart="8dp"/>
これは問題ないように見えますが、テキストが使用可能なスペースよりも長い場合は…
| |
|<-[TextView Larger Than The Space Avail]|
| |
テキストビューには、これらを指定するスタイルがあります。
<item name="Android:lines">1</item>
<item name="Android:maxLines">1</item>
<item name="Android:ellipsize">end</item>
だからそれは動作するはずですが、右側までスライドさせてからstopまでどのような制約が必要かわかりませんそこにスペースがないことをテキストビューに認識させます。
私は何が欠けていますか?
注:textviewの幅を0dpに設定すると機能しますが、画像は常に右側になります(水平バイアスは無視されるようです)
注2: 私はこれをベータ2でも試しましたが、実際、ベータ3には ビジュアルエディタのバグ があるようです。
[〜#〜] update [〜#〜]:Xcode/AutoLayoutでこれを複製しようとしました:
これは短いテキストでどのように見えるかです
同じレイアウトで、テキストビューに長いテキストを入力するだけです…
あなたが見ることができるように、画像ビューのトレイル(右)制約は言う:あなたは右マージンから8以上ポイントです。
また、ラベル(textView)の左側に固定されています。
私がTwitterから学んだことから、現時点ではAndroidのConstraintLayoutではこれは不可能かもしれません: Source
_ConstraintLayout 1.1.0
_を使用している場合、使用する正しいプロパティは、古い_app:layout_constrainedWidth="true"
_(および対応する高さ)の代わりに_app:layout_constraintWidth_default="wrap"
_です。
Constraint Layouts 1.0.2を使用しており、_app:layout_constraintWidth_default="wrap"
_(1.0.0で導入されたが、この投稿で使用していたベータ版にはないプロパティ)を使用したネストの少ないソリューションを見つけました。
FrameLayout
を含むLinearLayout
の代わりに、すべてを削除して次のようにすることができます。
_ <Android.support.constraint.ConstraintLayout
Android:id="@+id/new_way_container"
Android:layout_height="wrap_content"
Android:layout_width="0dp" // THIS GUY USES ALL THE WIDTH.
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
Android:ellipsize="end"
Android:id="@+id/some_text"
Android:layout_height="wrap_content"
Android:layout_width="0dp" //NO WRAP CONTENT, USE CONSTRAINTS
Android:lines="1"
Android:maxLines="1"
app:layout_constraintEnd_toStartOf="@+id/disclosure_arrow"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintHorizontal_chainStyle="packed" //CHAIN IT for biasing.
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="wrap" /> //THIS IS THE KEY THAT WILL CAUSE THIS TO WORK
<ImageView
Android:id="@+id/disclosure_arrow"
Android:layout_height="wrap_content"
Android:layout_width="10dp"
app:layout_constraintBottom_toTopOf="@id/some_text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/some_text"
app:layout_constraintTop_toBottomOf="@id/some_text"
app:srcCompat="@drawable/your_vector_image" />
</Android.support.constraint.ConstraintLayout>
_
これは、ハッキングやガイドライン、ハードコードされたサイズなしで、私が望むものを正確に実行します。
TextViewはConstraintsによって提供されるサイズを使用します(通常の状況では、これは間違っているか、「親」を超えて大きくなることを意味します)が、新しい属性のおかげで、これらの制約はコンテンツは小さい/大きい。
IOSの優先度よりもはるかに優れていると言わざるを得ません。 (少なくとも、私にとっては把握しやすいです)。この件についてGoogleに賛成:)
Nicolas Roardの答えに基づいて、基本的に使用可能なスペースを計算し、TextViewのmaxWidthをプログラムで設定するカスタムコンテナーを作成しました。別のクラス、単体テスト、バグの可能性のあるセットなどをプロジェクトに追加する代わりに、少し少ない効率的いくつかのレイアウトをネストする方法を試しました。夜明けからレイアウトをネストしており、これがスクロールリストビューに表示されたり移動したりすることはほとんどない(またはまったくない)ことと、ConstraintLayoutsを使用して階層のほとんどをフラット化することを考慮します(これまでにないように) !)、それから私は少し入れ子になっているとは思わないこれがより良くサポートされるまではそれは悪い。
つまり、基本的には、FrameLayoutを使用します。FrameLayoutは、設計上最適化(または考え)して、1人の子を作成します(複数の子を含めることができます)。このFrameLayoutは、ConstraintLayoutルールが次のように適用されたものです。
_ <FrameLayout
Android:id="@+id/hostTextWithCaretContainer"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent">
<!-- MY CONTENT GOES HERE -->
</FrameLayout>
_
したがって、私のrealアプリでは、このFrameLayoutは、左にアイコンやその他のものがある別のConstraintLayout内にありますが、この例のために、左/右を「固定」する必要があると想像してくださいこのFrameLayoutを、占有するスペースに合わせます。この例では、すべての制約でparent
を使用していますが、このFrameLayoutの左右に他のウィジェットがある可能性があります。 ConstraintLayoutの魔法のおかげで、これはすべての使用可能なスペースを占有します。
次に、トリックの2番目の部分があります。ConstraintLayoutはFrameLayoutが現在の「すべてのスペース」を使用し、それ以上(またはそれ以下)使用しないことを保証するため、LinearLayoutを内部で使用できます。
_ <LinearLayout
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:orientation="horizontal">
<TextView
Android:id="@+id/textView"
Android:layout_height="wrap_content"
Android:layout_width="0dp"
tools:text="Some Text"
Android:text="Some Text"
Android:textAlignment="viewStart"
Android:layout_gravity="center_vertical"
Android:gravity="start"
Android:ellipsize="end"
Android:maxLines="1"
Android:layout_weight="1"/>
<ImageView
Android:id="@+id/caret"
Android:layout_width="8dp"
Android:layout_height="8dp"
app:srcCompat="@drawable/ic_selection"
Android:contentDescription=""
Android:layout_gravity="center_vertical"
Android:layout_marginStart="8dp"
Android:layout_marginEnd="8dp" />
</LinearLayout>
_
鋭い読者は、LinearLayoutの幅に_wrap_content
_が含まれていることに気付くでしょう。これは、子TextViewが0dpの幅と1のweight
を持つことができるために非常に重要です他のすべてのウィジェットが幅を計算した後に利用可能な空きスペース。
この特定のケースでは、他の子(ImageView)caret
には重みが指定されておらず、固定幅があるため、TextViewは他の人と空き領域を共有/分割する必要がなく、すべてを使用できます(ただし、空きスペースのみ。幅が0dpであることを思い出してください。
この非効率的アプローチは、ConstraintLayoutが少ないとはいえ、私が望むものを効果的に達成しますMagic.
プラス面として、カスタムビューを作成し、数学を実行し、すべての数学が完了した後にrequestLayout()
を発行する必要はありませんでした。この非効率的なアプローチはスケーリングする/すべきであり、ConstraintLayoutが有効な代替手段を提供するまで、それで十分かもしれません。
ソーシャルメディアで返信し、最終的にはこれについて考える時間を取ったGoogleエンジニアへの叫び。将来、ConstraintLayout 1.1に関するタスクやストーリーポイントを書いているときに、彼らはこれを覚えており、良い解決策を考え出すかもしれません。
実際、TextViewsの場合の方法は次のとおりです。Android:maxWidth
を使用します。
<TextView
Android:id="@+id/textView7"
Android:maxWidth="200dp"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:maxLines="1"
Android:ellipsize="end"
Android:text="TextViewTextViewTextViewTextViewTextViewTextViewTextViewTextViewTextView"
tools:layout_editor_absoluteY="72dp"
Android:layout_marginStart="16dp"
app:layout_constraintLeft_toLeftOf="parent"
Android:layout_marginLeft="16dp" />
<Button
Android:id="@+id/button20"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="Button"
tools:layout_editor_absoluteY="56dp"
Android:layout_marginStart="8dp"
app:layout_constraintLeft_toRightOf="@+id/textView7"
Android:layout_marginLeft="8dp" />
正確にあなたが尋ねたものではありません(幅を制限するためにサイズを知って設定する必要があります)が、ConstraintLayout自体でそれをサポートするまであなたを助けるかもしれません。
ImageViewのマージンが負の制約レイアウトで相対レイアウトを使用できます。 Android:layout_marginRight="26dp"
およびAndroid:layout_marginLeft="-26dp"
に注意してください
<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"
Android:orientation="vertical">
<RelativeLayout
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_margin="8dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
Android:id="@+id/textView"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_centerVertical="true"
Android:layout_gravity="center_vertical"
Android:layout_marginRight="26dp"
Android:ellipsize="end"
Android:gravity="start"
Android:maxLines="1"
Android:text="Some text" />
<ImageView
Android:id="@+id/imageView"
Android:layout_width="24dp"
Android:layout_height="24dp"
Android:layout_centerVertical="true"
Android:layout_marginLeft="-26dp"
Android:layout_toRightOf="@+id/textView"
Android:contentDescription=""
Android:src="@drawable/ic_browser" />
</RelativeLayout>
</Android.support.constraint.ConstraintLayout>
私の場合、2018年7月からのMartinからのアップデートは機能しません:
ConstraintLayout 1.1.0を使用している場合、使用する正しいプロパティは、古い
app:layout_constrainedWidth="true"
(および対応する高さ)の代わりにapp:layout_constraintWidth_default="wrap"
です。
Android:width="wrap_content"
でのテキストビューにはapp:layout_constrainedWidth="true"
を使用する必要があります。 Android:layout_width="0dp"
(match_constraint)は、私の場合、短い文字列に合わせてテキストビューを拡大します。
同じ結果を得る別の可能性は、代わりにフラグAndroid:layout_width="0dp"
でapp:layout_constraintWidth_max="wrap"
を使用することです。
制約レイアウトのフラグの詳細については、ドキュメントをご覧ください: https://developer.Android.com/reference/Android/support/constraint/ConstraintLayout
この回答は、Martin Marconciniの回答( https://stackoverflow.com/a/40491128/1151701 )に触発されています。階層を削減するために、制約レイアウトを単純なビューに置き換えることができます。
<TextView
Android:ellipsize="end"
Android:id="@+id/some_text"
Android:layout_height="wrap_content"
Android:layout_width="0dp"
Android:lines="1"
Android:maxLines="1"
app:layout_constraintEnd_toStartOf="@+id/disclosure_arrow"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="wrap" />
<ImageView
Android:id="@+id/disclosure_arrow"
Android:layout_height="wrap_content"
Android:layout_width="10dp"
app:layout_constraintBottom_toTopOf="@id/some_text"
app:layout_constraintEnd_toEndOf="@id/view_guide"
app:layout_constraintStart_toEndOf="@id/some_text"
app:layout_constraintTop_toBottomOf="@id/some_text"
app:srcCompat="@drawable/your_vector_image" />
<View
Android:id="@+id/view_guide"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
ところで、私はConstraintLayout androidx.constraintlayout:constraintlayout:2.0.0-alpha3
を使用していますが、app:layout_constrainedWidth="true"
はこの場合期待どおりに機能します。ここでapp:layout_constraintWidth_default="wrap"
を使用しました