質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

解決済

3回答

1691閲覧

ConstralintLayoutでセンタリングしつつ他のViewとかぶらせない

rkrd

総合スコア35

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

0グッド

2クリップ

投稿2020/03/18 03:48

前提・実現したいこと

ImageView と TextView だけのシンプルなレイアウトです。
TextView は parent の中央に配置します。
ImageView は TextView の左に配置します。
TextViewは1行のみ、長い場合は「...」で省略します。

以下のようなレイアウトを作成し、いったんはうまくいきました。

XML

1<?xml version="1.0" encoding="utf-8"?> 2<layout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 xmlns:tools="http://schemas.android.com/tools"> 5 6 <data> 7 8 <variable 9 name="textString" 10 type="String" /> 11 </data> 12 13 <androidx.constraintlayout.widget.ConstraintLayout 14 android:layout_width="match_parent" 15 android:layout_height="match_parent" 16 tools:context=".MainActivity"> 17 18 <ImageView 19 android:id="@+id/imageView" 20 android:layout_width="wrap_content" 21 android:layout_height="wrap_content" 22 android:layout_marginStart="12dp" 23 app:layout_constraintBottom_toBottomOf="parent" 24 app:layout_constraintStart_toStartOf="parent" 25 app:layout_constraintTop_toTopOf="parent" 26 app:srcCompat="@android:drawable/btn_star_big_on" 27 tools:layout_editor_absoluteX="13dp" 28 tools:layout_editor_absoluteY="18dp" /> 29 30 <TextView 31 android:layout_width="wrap_content" 32 android:layout_height="wrap_content" 33 android:layout_marginStart="12dp" 34 android:layout_marginEnd="12dp" 35 android:ellipsize="end" 36 android:maxLines="1" 37 android:text="@{textString}" 38 app:layout_constraintBottom_toBottomOf="parent" 39 app:layout_constraintEnd_toEndOf="parent" 40 app:layout_constraintStart_toStartOf="parent" 41 app:layout_constraintTop_toTopOf="parent" 42 tools:text="センタリング" /> 43 44 </androidx.constraintlayout.widget.ConstraintLayout> 45</layout>

発生している問題、試したこと

TextView に設定する文字列が長い場合、左に設置した ImageView と TextViewが重なってしまいます。
そのため、TextView を app:layout_constraintStart_toStartOf="parent" としていたのを
app:layout_constraintStart_toEndOf="@id/imageView" としたところ、文字列が長くてもImageViewとは重ならなくなりました。
しかしながら、これでは文字列が短い場合に、親の中央ではなく、ImageViewのサイズ分 右にずれてしまいます。

Barrier を使って、textViewのstart位置を parentや barrierにしてみましたが、結果変わらずでした。

右にImageViewと同じサイズのViewを設置し、その中でセンタリングすれば中央に表示されますが、今回 TextView は右端(マージンはありますが)まで伸ばしたいのです。

知りたいこと

TextViewは親のセンターに設置しつつ、文字列が長くなった場合は左に設置したViewに重ならないようにするにはどうすればいいでしょうか。
XMLだけでは無理でしょうか。

補足情報(FW/ツールのバージョンなど)

Android Stduio 3.6
targetSdkVersion 29
constraintlayout:1.1.3

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

自己解決

以下のようにして解決しました。
XML側で

  • Imageと同サイズのSpaceを右端にも配置
  • DataBinging の varibale に Spaceのvisibleを切り替えるための変数を追加

そしてKotlinコード側で TextView が省略されている場合は Spaceを非表示にしました。

XML

1<?xml version="1.0" encoding="utf-8"?> 2<layout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 xmlns:tools="http://schemas.android.com/tools"> 5 6 <data> 7 8 <import type="android.view.View" /> 9 10 <variable 11 name="textString" 12 type="String" /> 13 14 <variable 15 name="spaceVisible" 16 type="Boolean" /> 17 </data> 18 19 <androidx.constraintlayout.widget.ConstraintLayout 20 android:layout_width="match_parent" 21 android:layout_height="56dp" 22 tools:context=".MainActivity"> 23 24 <ImageView 25 android:id="@+id/imageView" 26 android:layout_width="@dimen/image_size" 27 android:layout_height="@dimen/image_size" 28 android:layout_marginStart="@dimen/image_margin" 29 app:layout_constraintBottom_toBottomOf="parent" 30 app:layout_constraintStart_toStartOf="parent" 31 app:layout_constraintTop_toTopOf="parent" 32 app:srcCompat="@android:drawable/btn_star_big_on" 33 tools:layout_editor_absoluteX="13dp" 34 tools:layout_editor_absoluteY="18dp" /> 35 36 <TextView 37 android:id="@+id/textView" 38 android:layout_width="0dp" 39 android:layout_height="wrap_content" 40 android:layout_marginStart="12dp" 41 android:layout_marginEnd="12dp" 42 android:ellipsize="end" 43 android:gravity="center" 44 android:maxLines="1" 45 android:text="@{textString}" 46 app:layout_constraintBottom_toBottomOf="parent" 47 app:layout_constraintEnd_toStartOf="@id/space" 48 app:layout_constraintStart_toEndOf="@id/imageView" 49 app:layout_constraintTop_toTopOf="parent" 50 tools:text="センタリング" /> 51 52 <Space 53 android:id="@+id/space" 54 android:layout_width="@dimen/image_size" 55 android:layout_height="@dimen/image_size" 56 android:layout_marginEnd="@dimen/image_margin" 57 android:visibility="@{spaceVisible ? View.VISIBLE : View.GONE}" 58 app:layout_constraintBottom_toBottomOf="parent" 59 app:layout_constraintEnd_toEndOf="parent" 60 app:layout_constraintTop_toTopOf="parent" /> 61 </androidx.constraintlayout.widget.ConstraintLayout> 62</layout>

Kotlin

1 override fun onCreate(savedInstanceState: Bundle?) { 2 super.onCreate(savedInstanceState) 3 setContentView(R.layout.activity_main) 4 5 binding.textString = "長い長い長い長い長い長い長い長い長い長い文字列" 6 binding.textView.treeObserver { 7 if (it.layout.getEllipsisCount(0) > 0 ) { 8 binding.spaceVisible = false 9 } 10 } 11 12 binding.spaceVisible = true 13 } 14 15 fun TextView.treeObserver(callback: (textView: TextView) -> Unit) { 16 val listener = object : ViewTreeObserver.OnGlobalLayoutListener { 17 override fun onGlobalLayout() { 18 callback(this@treeObserver) 19 viewTreeObserver.removeOnGlobalLayoutListener(this) 20 return 21 } 22 } 23 viewTreeObserver.addOnGlobalLayoutListener(listener) 24 } 25

投稿2020/03/23 02:29

rkrd

総合スコア35

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2020/03/23 03:33

ありがとうございました.
guest

0

ご提示の ConstralintLayout によるセンタリングは, (上下)左右の隙間を均一にすることによって "結果的に" センタリングされているということですので, 条件によって隙間(の制約)を変えるには, 何某かのコードが必要になるように思います.

投稿2020/03/18 05:08

jimbe

総合スコア12646

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rkrd

2020/03/18 06:15 編集

回答ありがとうございます。 なるほどConstralintLayoutのセンタリングはたしかにそうですね。 では、ConstralintLayoutを諦めて、RelativeLayoutで明示的にCenterに寄せた場合はどうでしょうか。 以下試して見ました。 ```XML <?xml version="1.0" encoding="utf-8"?> <layout 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"> <data> <variable name="textString" type="String" /> </data> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".Main2Activity"> <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="12dp" android:layout_alignParentStart="true" android:layout_centerVertical="true" app:srcCompat="@android:drawable/btn_star_big_on" tools:layout_editor_absoluteX="13dp" tools:layout_editor_absoluteY="18dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="12dp" android:layout_marginEnd="12dp" android:ellipsize="end" android:maxLines="1" android:text="@{textString}" android:layout_centerInParent="true" tools:text="センタリング" /> </RelativeLayout> </layout> ``` これだと、ConstralintLayoutと同じで長い文字列で ImageView と TextViewが重なりました。 TextViewに `android:layout_toRightOf="@id/imageView"` を追加したら重ならなくなったものの、 `android:layout_centerInParent="true"`が効かなくなったのか ImageViewの横に表示されます。 TextView をmatch_parent にして gravitiyを centerにしたら、ConstralintLayoutと同じでImageView分中心からずれます。 ConstralintLayout以外でもXMLのみでは無理ということでしょうか。
jimbe

2020/03/18 06:38

> ConstralintLayout以外でもXMLのみでは無理ということでしょうか すいませんが, Layout の仕様・使用方法に詳しいわけではありません. 何を用いれば・どこまで出来るかを調査するつもりはありませんので, 追加回答は出来ません. 「私だったらテキトウに ViewGroup を作って対応するかもしれません」ということでご勘弁願います.
rkrd

2020/03/19 01:12

ありがとうございます。 今回は、右端にも左のImageViewと同サイズの Space を設置してセンタリングし、TextView が長い場合のみSpaceのVisibilityを変えることで対応しました。
jimbe

2020/03/19 10:31 編集

もし宜しかったら, その辺りのコードやレイアウトを自己回答としてご提示頂いて, そちらをBAにされては如何でしょうか. 同じようなレイアウトを作ろうという方にはそのほうが有用な情報かと思います.
rkrd

2020/03/23 02:34

そうですね。 自己回答を追記しました。ご指摘ありがとうございます。
guest

0

ちょうどやろうとしていた内容と合致していたのでBAが参考になりました。
通常のViewの場合はこれで問題ないですが、RecyclerViewのアイテムだとonGlobalLayoutに来てもまだlayoutがnullの場合が多く、結局、postDelayedでnullではなくなるまで投げ続けるようにして、解決できました。

Kotlin

1private fun layoutTextViewEllipsized(){ 2 binding.textView.postDelayed( { 3 if(binding.textView.layout==null){ 4 layoutTextViewEllipsized() 5 return@postDelayed 6 } 7 if (binding.textView.layout.getEllipsisCount(0) > 0 ) { 8 binding.spaceVisible = false 9 } 10 }, 500) 11}

投稿2023/06/23 03:20

les.kasa

総合スコア2

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問