There are many answers to this and almost equivalent, repetitive questions about SO. Proposed approaches usually work, however. Put it in LinearLayout , wrap everything in an optional RelativeLayout , use TableLayout ; they all seem to solve it for a simpler layout, but if you need these two TextView inside something more complex or the same layout will be reused, for example using RecyclerView , everything will break very quickly.
The only solution I found that really works all the time, no matter how big the layout you put it in, is a custom layout. It is very simple to implement, and, being as thin as possible, it will support the layout quite flat, it is easy to maintain, so in the end I think this is the best solution to the problem.
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); } }
The implementation could not be simpler, it simply measures two texts (or any other child views in fact), and if their total width exceeds the width of the layout, reduces the width of the first view.
And if you need changes, for example. to align the second text to the baseline of the first, you can also easily solve this problem:
text2View.layout(childLeft + text1Width, childTop + text1Height - text2Height, childLeft + text1Width + text2Width, childTop + text1Height);
Or any other solution, for example, reducing the second representation in relation to the first, aligning to the right, etc.