I have a ConstraintLayout, TextView and three buttons.
TextView is always visible. But buttons are by default gone and shows in adapter view depends on the data type (thats why I am not constraining end of the text to start of the button).
So the problem is that when text is too long it overlaps with the button. So how can I write the code that in case text overlaps it goes to the second line. Here is my xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/myContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="24dp"
android:paddingEnd="24dp"
android:paddingTop="16dp"
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">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/myText"
android:layout_width="0dp"
android:layout_height="wrap_content"
tools:text="Here is some long text"
app:layout_constraintVertical_bias=".4"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
/>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/buttonOne"
android:layout_width="wrap_content"
android:layout_height="32dp"
android:background="@drawable/black"
android:enabled="true"
android:gravity="center|center_vertical"
android:paddingHorizontal="@dimen/dp16"
android:paddingVertical="@dimen/dp4"
android:text="@string/buttonOneText"
app:layout_constraintEnd_toEndOf="parent"
app:backgroundTint="@null"
android:visibility="gone"/>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/buttonTwo"
android:layout_width="wrap_content"
android:layout_height="32dp"
android:background="@drawable/red"
android:enabled="true"
android:gravity="center|center_vertical"
android:paddingHorizontal="@dimen/dp16"
android:paddingVertical="@dimen/dp4"
android:text="@string/buttonTwoText"
android:textSize="@dimen/sp14"
android:textColor="@color/brand_500"
app:layout_constraintEnd_toEndOf="parent"
app:backgroundTint="@null"
android:visibility="gone"/>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/buttonThree"
android:layout_width="wrap_content"
android:layout_height="@dimen/dp32"
android:background="@drawable/yellow"
android:enabled="true"
android:gravity="center|center_vertical"
android:paddingHorizontal="@dimen/dp16"
android:paddingVertical="@dimen/dp4"
android:text="@string/buttonThreeText"
android:textSize="@dimen/sp14"
android:textColor="@color/black_500"
app:layout_constraintEnd_toEndOf="parent"
app:backgroundTint="@null"
android:visibility="gone"/>
</androidx.constraintlayout.widget.ConstraintLayout>
1
Please also remember to share the UI showing the constraints to easier understand your problem. Moreover, what I can make out from your XML is that you need to constraint the end of your TextView to the start the button; and you would also need to follow this answer
You need to add Constraint Between Your widget with layout constraint like this “app:layout_constraintTop_toBottomOf=”@id/Your Top Widget Id Value”
This is changed xml code base on your xml.
<?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:id="@+id/myContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="24dp"
android:paddingTop="16dp"
android:paddingEnd="24dp">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/myText"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias=".4"
tools:text="Here is some long text" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/buttonOne"
android:layout_width="wrap_content"
android:layout_height="32dp"
android:background="@drawable/black"
android:enabled="true"
android:gravity="center|center_vertical"
android:paddingHorizontal="@dimen/dp16"
android:paddingVertical="@dimen/dp4"
android:text="@string/buttonOneText"
android:visibility="gone"
app:backgroundTint="@null"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/myText" /><!-- *** <<< You need to add this like for constraint TopToBottom *** -->
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/buttonTwo"
android:layout_width="wrap_content"
android:layout_height="32dp"
android:background="@drawable/red"
android:enabled="true"
android:gravity="center|center_vertical"
android:paddingHorizontal="@dimen/dp16"
android:paddingVertical="@dimen/dp4"
android:text="@string/buttonTwoText"
android:textColor="@color/brand_500"
android:textSize="@dimen/sp14"
android:visibility="gone"
app:backgroundTint="@null"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/buttonOne" /> <!-- *** <<< You need to add this like for constraint TopToBottom *** -->
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/buttonThree"
android:layout_width="wrap_content"
android:layout_height="@dimen/dp32"
android:background="@drawable/yellow"
android:enabled="true"
android:gravity="center|center_vertical"
android:paddingHorizontal="@dimen/dp16"
android:paddingVertical="@dimen/dp4"
android:text="@string/buttonThreeText"
android:textColor="@color/black_500"
android:textSize="@dimen/sp14"
android:visibility="gone"
app:backgroundTint="@null"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/buttonTwo" /> <!-- *** <<< You need to add this like for constraint TopToBottom *** -->
</androidx.constraintlayout.widget.ConstraintLayout>
And Then,If you need very long text, you need to add a NestedScrollView to make all the buttons appear on your screen with the scroll function.
This is changed xml code base on your xml.
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView 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="match_parent"
android:layout_height="wrap_content"> <!-- "*** If you need a very long text. You need to add a NestedScrollView to make all the buttons appear on your screen. ***"-->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/myContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="24dp"
android:paddingTop="16dp"
android:paddingEnd="24dp">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/myText"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias=".4"
tools:text="Here is some long text" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/buttonOne"
android:layout_width="wrap_content"
android:layout_height="32dp"
android:background="@drawable/black"
android:enabled="true"
android:gravity="center|center_vertical"
android:paddingHorizontal="@dimen/dp16"
android:paddingVertical="@dimen/dp4"
android:text="@string/buttonOneText"
android:visibility="gone"
app:backgroundTint="@null"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/myText" /> <!-- *** <<< You need to add this like for constraint TopToBottom *** -->
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/buttonTwo"
android:layout_width="wrap_content"
android:layout_height="32dp"
android:background="@drawable/red"
android:enabled="true"
android:gravity="center|center_vertical"
android:paddingHorizontal="@dimen/dp16"
android:paddingVertical="@dimen/dp4"
android:text="@string/buttonTwoText"
android:textColor="@color/brand_500"
android:textSize="@dimen/sp14"
android:visibility="gone"
app:backgroundTint="@null"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/buttonOne" /> <!-- *** <<< You need to add this like for constraint TopToBottom *** -->
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/buttonThree"
android:layout_width="wrap_content"
android:layout_height="@dimen/dp32"
android:background="@drawable/yellow"
android:enabled="true"
android:gravity="center|center_vertical"
android:paddingHorizontal="@dimen/dp16"
android:paddingVertical="@dimen/dp4"
android:text="@string/buttonThreeText"
android:textColor="@color/black_500"
android:textSize="@dimen/sp14"
android:visibility="gone"
app:backgroundTint="@null"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/buttonTwo" /> <!-- *** <<< You need to add this like for constraint TopToBottom *** -->
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
You should need to read about ConstraintLayout ( Relative positioning ) with below links
https://developer.android.com/reference/androidx/constraintlayout/widget/ConstraintLayout
https://developer.android.com/develop/ui/views/layout/constraint-layout
Thank You.
You didn’t fully explain what the intended UI output is, but based on the code and what you mentioned, I guess you have 3 buttons, with only one visible at a time while the other two are hidden. Sometimes, all three buttons are hidden. You want the end of the TextView to be constrained to the start of the button when one is present, and if no buttons are present, the TextView should expand and take up the full width.
You probably want your program to switch between the following four states:
Now you have two ways
, each with its advantages and disadvantages.
1. Update Constraint Dynamically:
XML file:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- TextView -->
<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Some text"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:ellipsize="end"/>
<!-- Button 1 -->
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:visibility="gone" /> <!-- Initially hidden -->
<!-- Button 2 (same position as Button 1) -->
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:visibility="gone" /> <!-- Initially hidden -->
<!-- Button 3 (same position as Button 1 and Button 2) -->
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:visibility="gone" /> <!-- Initially hidden -->
</androidx.constraintlayout.widget.ConstraintLayout>
and use this snippet code:
val textView = findViewById<TextView>(R.id.textView)
val button1 = findViewById<Button>(R.id.button1)
val button2 = findViewById<Button>(R.id.button2)
val button3 = findViewById<Button>(R.id.button3)
val constraintLayout = findViewById<ConstraintLayout>(R.id.constraintLayout)
// Function to update constraints based on visible button
fun updateConstraints() {
val constraintSet = ConstraintSet()
constraintSet.clone(constraintLayout)
when {
button1.visibility == View.VISIBLE -> {
// Constrain TextView's end to button1's start
constraintSet.connect(R.id.textView, ConstraintSet.END, R.id.button1, ConstraintSet.START)
}
button2.visibility == View.VISIBLE -> {
// Constrain TextView's end to button2's start
constraintSet.connect(R.id.textView, ConstraintSet.END, R.id.button2, ConstraintSet.START)
}
button3.visibility == View.VISIBLE -> {
// Constrain TextView's end to button3's start
constraintSet.connect(R.id.textView, ConstraintSet.END, R.id.button3, ConstraintSet.START)
}
else -> {
// No buttons visible, constrain TextView's end to parent's end
constraintSet.connect(R.id.textView, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END)
}
}
// Apply the updated constraints
constraintSet.applyTo(constraintLayout)
}
// Example of making a button visible and updating constraints
button1.visibility = View.VISIBLE
button2.visibility = View.GONE
button3.visibility = View.GONE
// Call the function to update constraints
updateConstraints()
2. Use a Layout for buttons inside ConstraintLayout:
Xml file:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- TextView -->
<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Some text"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/buttonLayout"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:ellipsize="end"/>
<!-- Layout for buttons -->
<LinearLayout
android:id="@+id/buttonLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<!-- Button 1 -->
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 1"
android:visibility="gone" />
<!-- Button 2 -->
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 2"
android:visibility="gone" />
<!-- Button 3 -->
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 3"
android:visibility="gone" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
When you want all the buttons to be gone, you should set that layout Gone
. And when one of these buttons is visible, that layout should be visible. Like this:
val buttonLayout = findViewById<LinearLayout>(R.id.buttonLayout)
val button1 = findViewById<Button>(R.id.button1)
val button2 = findViewById<Button>(R.id.button2)
val button3 = findViewById<Button>(R.id.button3)
// Function to update visibility of button layout
fun updateButtonLayoutVisibility() {
if (button1.visibility == View.GONE && button2.visibility == View.GONE && button3.visibility == View.GONE) {
buttonLayout.visibility = View.GONE
} else {
buttonLayout.visibility = View.VISIBLE
}
}
// Example: Show Button 1 and hide Button 2 and 3
button1.visibility = View.VISIBLE
button2.visibility = View.GONE
button3.visibility = View.GONE
// Call function to update layout visibility
updateButtonLayoutVisibility()