My layout:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<TextView
android:id="@ id/crime_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Crime Title" />
<TextView
android:id="@ id/crime_date"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/crime_title"
android:text="Crime Date" />
<Button
android:id="@ id/crime_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="@id/crime_title" />
</RelativeLayout>
The output:
As you can see the button goes beyond the border that is composed by these two TextViews, but i want it to accurately match it. I also tried to do it with LinearLayout that have two LinearLayouts instead of RelativeLayout but I didn't succeed. So how can i do it ?
CodePudding user response:
ConstraintLayout
is a good option because it gives us much more precise control.
<?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="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/holo_red_light"
android:padding="8dp">
<TextView
android:id="@ id/crime_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
app:layout_constraintEnd_toStartOf="@ id/crime_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@ id/crime_button"
tools:text="Crime Title Crime Title Crime Title Crime Title" />
<TextView
android:id="@ id/crime_date"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
app:layout_constraintBottom_toBottomOf="@ id/crime_button"
app:layout_constraintEnd_toStartOf="@ id/crime_button"
app:layout_constraintStart_toStartOf="parent"
tools:text="Crime Date" />
<com.google.android.material.button.MaterialButton
android:id="@ id/crime_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Crime Button" />
</androidx.constraintlayout.widget.ConstraintLayout>
In this case, the first TextView
is linked to the top
of the Button
, and the second TextView
is linked to the bottom
of the Button
. But it will only have a nice result if we know the fixed height of all the components, so it's ideal to put a maximum of lines in the TextView
, as I did in the example code itself.
Another example allowing multiple lines for the TextView:
<?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="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<TextView
android:id="@ id/crime_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@ id/crime_date"
app:layout_constraintEnd_toStartOf="@ id/crime_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Crime Title Crime Title Crime Title Crime Title" />
<TextView
android:id="@ id/crime_date"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@ id/crime_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@ id/crime_title"
tools:text="Crime Date Crime Date Crime Date Crime Date" />
<com.google.android.material.button.MaterialButton
android:id="@ id/crime_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Crime Button" />
</androidx.constraintlayout.widget.ConstraintLayout>
In this second case, the TextViews
are linked only to the parent
, so the ConstraintLayout
will scale its size, and as the Button
is also linked to the parent
, it will stay in the middle.
There are still other possible scenarios, where it could be necessary to use a great resource of ConstraintLayout
called
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<TextView
android:id="@ id/crime_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Crime Title"
app:layout_constraintEnd_toStartOf="@id/crime_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@ id/crime_date"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_below="@id/crime_title"
android:text="Crime Date"
app:layout_constraintEnd_toStartOf="@id/crime_button"
app:layout_constraintStart_toStartOf="@id/crime_title"
app:layout_constraintTop_toBottomOf="@id/crime_title" />
<androidx.appcompat.widget.AppCompatButton
android:id="@ id/crime_button"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_alignTop="@id/crime_title"
android:layout_alignEnd="@id/crime_title"
android:background="@color/colorPrimaryDark"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toEndOf="@id/crime_title"
app:layout_constraintTop_toTopOf="@id/crime_title" />
</androidx.constraintlayout.widget.ConstraintLayout>