问题
I have a toolbar like component implementation, that I'm having trouble with the layout in all situations. It has a left icon, a title and a right menu/button. I need the title to be centered on the full screen (or at least the full width of the layout) but also to not overlap with the other components. So the width of the title would have to be constrained by the left icon and the right button.
I have two intermediary solutions but can't seem to find a way to combine them.
One is to center the title on the screen. The problem here is that the title overlaps with the right button (and would overlap with the left icon too, if large enough ...). Here is the layout XML:
<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">
<ImageView
android:id="@+id/bottomSheetHeaderIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/bottomSheetHeaderTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textAlignment="center"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="My also very very very very very long title" />
<TextView
android:id="@+id/right_action"
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="Really long string longer"/>
</androidx.constraintlayout.widget.ConstraintLayout>
The other is to center the title between the left icon and the right button. Now there is no overlap, but the title is not centered correctly. Since the two side elements have very different sizes, the title is only centered between them, which is no good. Here is the same layout with the constraints for this case:
<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">
<ImageView
android:id="@+id/bottomSheetHeaderIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/bottomSheetHeaderTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textAlignment="center"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/right_action"
app:layout_constraintStart_toEndOf="@+id/bottomSheetHeaderIcon"
app:layout_constraintTop_toTopOf="parent"
tools:text="My also very very very very very long title" />
<TextView
android:id="@+id/right_action"
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="Really long string longer"/>
</androidx.constraintlayout.widget.ConstraintLayout>
I'm trying to get away with just a XML layout solution, without having to do programmatically detect overlaps and change the layout.
Solutions with other layouts would also work, if they exist.
The problem is the same as the questions here and here, but I'm hoping that by giving more detail, this one gets an accepted solution.
回答1:
Here is a programatic answer to this question, that is what I'm using for now, but I'd really like a layout solution ...
I use the first layout, centered on the screen, and, as this is part of a custom view for me, add the following code to the constructor (title
is a reference to bottomSheetHeaderTitle
and rightAction
is right_action
, the left icon is assumed to always be smaller than the right action text).
viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
if (title.width > 0) {
if (title.right > rightAction.x) {
title.maxWidth = (2.0 * (width / 2.0 - (width - rightAction.x))).toInt()
}
viewTreeObserver.removeOnGlobalLayoutListener(this)
}
}
})
This code detects if the title overlaps the right action, and, if it does, adds a max width to it. The max width is the double of the distance between the center of the screen and the beginning of the right action.
来源:https://stackoverflow.com/questions/63848314/constraintlayout-center-view-on-full-screen-but-limit-width-to-not-overlap-with