Два TextViews бок о бок, только один для эллипсизации?

Я хочу, чтобы два элемента TextView отображались бок о бок (в элементе списка), один был выровнен слева, один – вправо. Что-то вроде:

 |<TextView> <TextView>| 

(Обозначают конечности экрана)

Тем не менее, TextView слева может иметь контент, который слишком длинный, чтобы поместиться на экране. В этом случае я хочу, чтобы он был эллипсисом, но все же отображал весь текст TextView . Что-то вроде:

 |This is a lot of conte...<TextView>| 

У меня было много попыток на этом, используя LinearLayout и RelativeLayout , и единственным решением, которое я придумал, является использование RelativeLayout и добавление marginRight влево TextView достаточно большим, чтобы очистить правильный TextView . Как вы можете себе представить, это не оптимально.

Есть ли другие решения?

Окончательное решение LinearLayout :

 <LinearLayout android:layout_height="wrap_content" android:layout_width="fill_parent" android:orientation="horizontal" > <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_weight="1" android:ellipsize="end" android:inputType="text" /> <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_weight="0" android:layout_gravity="right" android:inputType="text" /> </LinearLayout> 

Старое решение TableLayout :

 <TableLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:stretchColumns="1" android:shrinkColumns="0" > <TableRow> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ellipsize="end" android:singleLine="true" /> <TextView android:id="@+id/date" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1" android:singleLine="true" android:ellipsize="none" android:gravity="right" /> </TableRow> </TableLayout> 

Solutions Collecting From Web of "Два TextViews бок о бок, только один для эллипсизации?"

Используйте TableLayout и поместите оба TextView в строку таблицы, попробуйте. Я не пробовал

Просто идея, почему бы вам не объявить сначала в макете xml текстовое изображение справа и установить его ширину в качестве содержимого оболочки, android:layout_alignParentRight="true" и android:gravity="right" . Затем объявите текстовое изображение слева, установите его ширину как заполняющий родительский android:layout__toLeftOf , android:layout__toLeftOf = {идентификатор текстового поля справа}, имеющий RelativeView в качестве корневого представления.

Объявив сначала правильное текстовое представление, его требуемая ширина будет сначала вычислена и займет вид, а текстовое изображение слева займет оставшееся пространство представления.

Я все еще не пробовал этого, хотя это может дать вам некоторую идею.

[Обновить]

Я попытался создать макет ресурса xml … и он как-то работает …

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:id="@+id/right" android:layout_alignParentRight="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="right" android:text="right" > </TextView> <TextView android:id="@+id/left" android:layout_alignParentLeft="true" android:layout_toLeftOf="@id/right" android:layout_width="fill_parent" android:layout_height="wrap_content" android:ellipsize="end" android:lines="1" android:singleLine="true" android:maxLines="1" android:text="too looooooooooong ofskgjo sdogj sdkogjdfgds dskjgdsko jgleft" > </TextView> </RelativeLayout> 

Ответ LinearLayout работал для меня с этой же проблемой. Отправленный как отдельный ответ, потому что было непонятно, что делало и не работало для искателя.

Одно отличие. TableLayout был менее идеален для меня, потому что у меня было две строки данных, и я хотел, чтобы нижняя строка вела себя так, как описывает этот вопрос, и верхнюю строку для охвата области. На этот вопрос ответили другим вопросом: Colspan в TableLayout , но LinearLayout был проще.

Хотя получить ширину правой взял меня немного. Я включил настройку android lint с использованием ширины 0dp для элемента масштабирования для производительности.

 <LinearLayout android:layout_height="wrap_content" android:layout_width="fill_parent" android:orientation="horizontal" > <TextView android:layout_height="wrap_content" android:layout_width="0dp" android:layout_weight="1" android:ellipsize="end" android:inputType="text" /> <TextView android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_weight="0" android:layout_gravity="right" android:inputType="text" /> </LinearLayout> 

Есть много ответов на этот и практически эквивалентные, повторяющиеся вопросы о SO. Предлагаемые подходы обычно работают, как бы то ни было. LinearLayout его в LinearLayout , оберните все в дополнительный RelativeLayout , используйте TableLayout ; Все это, похоже, решает его для более простой компоновки, но если вам нужны эти два TextView внутри чего-то более сложного или один и тот же макет будет повторно использоваться, например, с помощью RecyclerView , все будет очень быстро сломаться.

Единственное решение, которое я нашел, действительно работает постоянно, независимо от того, какой большой макет вы его вложили, – это настраиваемый макет. Это очень просто реализовать, и, будучи таким худым, как это возможно, он будет поддерживать макет достаточно плоским, его легко поддерживать, поэтому в долгосрочной перспективе я считаю это лучшим решением проблемы.

 public class TwoTextLayout extends ViewGroup { public TwoTextLayout(Context context) { super(context); } public TwoTextLayout(Context context, AttributeSet attrs) { super(context, attrs); } public TwoTextLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = getChildCount(); if (count != 2) throw new IllegalStateException("TwoTextLayout needs exactly two children"); int childLeft = this.getPaddingLeft(); int childTop = this.getPaddingTop(); int childRight = this.getMeasuredWidth() - this.getPaddingRight(); int childBottom = this.getMeasuredHeight() - this.getPaddingBottom(); int childWidth = childRight - childLeft; int childHeight = childBottom - childTop; View text1View = getChildAt(0); text1View.measure(MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.AT_MOST)); int text1Width = text1View.getMeasuredWidth(); int text1Height = text1View.getMeasuredHeight(); View text2View = getChildAt(1); text2View.measure(MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(childHeight, MeasureSpec.AT_MOST)); int text2Width = text2View.getMeasuredWidth(); int text2Height = text2View.getMeasuredHeight(); if (text1Width + text2Width > childRight) text1Width = childRight - text2Width; text1View.layout(childLeft, childTop, childLeft + text1Width, childTop + text1Height); text2View.layout(childLeft + text1Width, childTop, childLeft + text1Width + text2Width, childTop + text2Height); } } 

Реализация не может быть проще, она просто измеряет два текста (или любые другие дочерние представления на самом деле), и если их общая ширина превышает ширину макета, уменьшает ширину первого вида.

И если вам нужны изменения, например. Чтобы выровнять второй текст с базовым уровнем первого, вы также можете легко решить это:

 text2View.layout(childLeft + text1Width, childTop + text1Height - text2Height, childLeft + text1Width + text2Width, childTop + text1Height); 

Или любое другое решение, подобное сокращению второго представления по отношению к первому, выравнивание по правому краю и т. Д.

Почему бы вам не поместить левое поле в правый TextView? Я использую этот подход для

 |<TextView> <ImageButton>| 

И это работает.