Есть много ответов на этот и практически эквивалентные, дублирующие вопросы по SO.Предлагаемые подходы обычно работают, вроде.Положите его в 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);
или любое другое решение, такое как сжатие второго вида относительно первого, выравнивание вправо,и т.д.