ConstraintLayout: center view on full screen but limit width to not overlap with side views

有些话、适合烂在心里 提交于 2021-02-04 21:40:15

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!