How to center a view in a ConstraintLayout without overlapping uneven neighbours
Asked Answered
L

3

7

I'm using a custom layout for my title bar, based on a ConstraintLayout. I need to center the title text without overlapping the buttons on either side. Currently I've got the title centered between the side buttons, but as they're different widths the title is not centered within the parent view.

This is what it currently looks like (centered between the two buttons rather than centered in the parent):

Current title bar layout

Is there any way to center the title within the parent, while ensuring it doesn't overlap the button text on either side (as this can change)?

To make it more complicated, I'd also like it to be the title that gets compressed instead of the button text if there isn't space for both to be displayed in full.

If I constrain both edges of my title to the parent and set it to wrap width then it almost works, until the button text gets a bit long.

Lay answered 12/6, 2019 at 8:32 Comment(1)
Not what any of us want, but I have a programmatic solution here: https://mcmap.net/q/1625770/-constraintlayout-center-view-on-full-screen-but-limit-width-to-not-overlap-with-side-viewsTangent
P
3

You should start from Center, then go left & right.

Try below solution, it should work as expected

<android.support.constraint.ConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <Button
            android:id="@+id/btn_at_the_start"
            android:layout_width="0dp"
            android:layout_height="45dp"
            android:gravity="center"
            android:text="Awards"
            app:layout_constraintEnd_toStartOf="@+id/tv_in_the_middle"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintWidth_percent="0.2" />

        <TextView
            android:id="@+id/tv_in_the_middle"
            android:layout_width="0dp"
            android:layout_height="45dp"
            android:ellipsize="end"
            android:gravity="center"
            android:textAlignment="center"
            android:padding="5dp"
            android:maxLines="2"
            android:text="Nominations"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintWidth_percent="0.6" />

        <ImageButton
            android:id="@+id/ibtn_at_the_end"
            android:layout_width="0dp"
            android:layout_height="45dp"
            android:background="@android:color/transparent"
            android:gravity="center_horizontal"
            android:src="@drawable/ic_add_white"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/tv_in_the_middle"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintWidth_percent="0.2" />
    </android.support.constraint.ConstraintLayout>
Pius answered 12/6, 2019 at 10:17 Comment(3)
Thanks for taking the time to write a comprehensive example! Will this work if the button/title text get longer though?Lay
Yes, it will get truncated if title is longer than 2 lines. Title maxLines you can change as per your requirement.Pius
Percents work great. To achieve wrap_content width i also added app:layout_constrainedWidth="true" and app:layout_constraintWidth_max="wrap"Havelock
B
1

To center the view you can give layout_width = "0dp" while connecting two sides of the view to other views. Then the center view takes the place as much as left for the view

Update

If you want to center inside parent then, others view would be your parent.

android:layout_width = "0dp"
android:layout_height = "wrap_content"
android:ellipsize = "end"
android:maxLines = "1"
app:layout_constraintEnd_toEndOf = "parent"
app:layout_constraintStart_toStartOf = "parent"
app:layout_constraintTop_toTopOf = "parent"
app:layout_constraintBottom_toOf = "parent"
Bluepoint answered 12/6, 2019 at 8:35 Comment(3)
That's how to center it between 2 views yes, but I'm trying to center in the parentLay
@Bluepoint That works for centering in the parent, but then it can overlap the button text if either gets too long. Thanks for your help though!Lay
That is why to centering in the parent there must not have other views on two sides of the view. In your case, just place the TextView center between two views, then align text in the center would solve your problemBluepoint
O
0

you can use

  1. app:layout_constraintTop_toTopOf
  2. app:layout_constraintStart_toStartOf

as shown below

<TextView android:id="@+id/nomination" 
android:layout_width="wrap_content"
android:layout_height="wrap_content" 
app:layout_constraintTop_toTopOf="@+id/someId1" 
app:layout_constraintBottom_toBottomOf="@+id/someId2" 
app:layout_constraintStart_toStartOf="@+id/awards" 
app:layout_constraintEnd_toEndOf="parent"/>
Observance answered 12/6, 2019 at 8:58 Comment(3)
Thanks for your answer. If I align start to start of the awards button then it doesn't prevent an overlap if the text is longLay
you can use app:layout_constraintGuide_percent="2" to give some weigth for the viewObservance
The OS throws an exception when I use this on something that's not a layout guideLay

© 2022 - 2024 — McMap. All rights reserved.