Doing it in Layout
This can be fixed using ConstraintLayout with:
packed horizontal chain
- 0 horizontal bias.
- Enable constraintWidth
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="sdrndesfntzrfndtzmufzksbnsfdn stnbhdsfbns sth st ömcfz,frznz"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/button"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/textView"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Doing it dynamically
If you still need to use LinearLayout, then you can do it programmtically. As you need to wrap_content both the TextView and Button in the same width, so logically this is not achievable because when the sum of widths is greater than the screen width, some view will be greedy on the other.
Therefore you decided to do that wrap_content until the button takes wraps its width without going off the end of the screen.
But now the TextView width shouldn't be wrap_content; instead it should be some fixed size; because if it still wrap_content it'll be greedy on the Button, and kick it off the screen or being squeezed like in your case.
So, we need to do some effort programmatically to know the screen width, so we will limit the TextView to the equation:
TextView_maxWidth = screenWidth - buttonWidth
Solution 1: Using LinearLayout
If we set the TextView text on the layout, now the button will be squeezed, and we couldn't determine the wrap_content size of the Button programmatically, so in this solution the textView text is set programmatically after we got the Button size.
layout (Nothing fancy):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
Behavior:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout root = findViewById(R.id.root);
root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
root.getViewTreeObserver()
.removeOnGlobalLayoutListener(this);
}
int width = root.getWidth();
Button button = findViewById(R.id.button);
int buttonWidth = button.getWidth();
int maxTextWidth = width - buttonWidth;
TextView textView = findViewById(R.id.textView);
textView.setMaxWidth(maxTextWidth);
textView.setText("drndesfntzrfndtzmufzksbnsfdn stnbhdsfbns sth st ömcfz,frznz");
}
});
}
Solution 2: Using ConstraintLayout
Unlike LinearLayout, ConstraintLayout can force the button size to be wrap_content without being squeezed, and therefore we can set the text of the TextView on layout.
Layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="sdrn desf ntzrf ndtz mufzk sbnsf dn sdrnde sf ntzrfn dtz mufzks bns fdn sd rn de sfnt zrf ndtzmufzk sbnsfdnstn bhdsfbns sth st ömcfz, frznz"
app:layout_constrainedWidth="true"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintStart_toEndOf="@id/textView"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Behavior:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ConstraintLayout root = findViewById(R.id.root);
root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
root.getViewTreeObserver()
.removeOnGlobalLayoutListener(this);
}
int width = root.getWidth();
Button button = findViewById(R.id.button);
int buttonWidth = button.getWidth();
int maxTextWidth = width - buttonWidth;
TextView textView = findViewById(R.id.textView);
textView.setMaxWidth(maxTextWidth);
}
});
}
Previews:


