Align baseline of TextView to Guideline in Constraint Layout

Viewed 2032

Hopefully I'm not being completely thick here, but I'm unable to align the baseline of a TextView to a Guideline in a ConstraintLayout. It appears the guideline does not have a baseline, which is pretty annoying. Does anyone know how I might achieve this? Here's a bit of layout xml that doesn't work (this is within a ConstraintLayout):

                 <TextView
                    android:id="@+id/textToAlignBaseline"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="20dp"
                    android:maxLines="1"
                    android:paddingRight="6dp"
                    android:textAppearance="@style/TextStyles.Body"
                    app:layout_constraintBaseline_toBaselineOf="@+id/guidelineBottomMargin"
                    app:layout_constraintLeft_toLeftOf="parent" />

                <Button
                    android:id="@+id/buttonToAlignBottom"
                    android:layout_width="wrap_content"
                    android:layout_height="39dp"
                    android:layout_marginRight="20dp"
                    android:background="@drawable/selector_button_bg"
                    android:paddingLeft="16dp"
                    android:paddingRight="16dp"
                    android:text="@string/clickme"
                    android:textAppearance="@style/TextStyles.Body"
                    app:layout_constraintBottom_toTopOf="@+id/guidelineBottomMargin"
                    app:layout_constraintRight_toRightOf="parent" />

                <android.support.constraint.Guideline
                    android:id="@+id/guidelineBottomMargin"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal"
                    app:layout_constraintGuide_end="20dp" />
3 Answers

I had this question when I tried to implement a two-line list according to Material Design, where the "Two-line item" baseline should be 32dp from the top:

Material Design spec

It looks like a plain View or Guideline doesn't have a baseline because it returns -1 from getBaseline. So what I ended up with is using an invisible TextView like this:

<TextView
    android:id="@+id/guideline"
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:layout_marginTop="32dp"
    android:textSize="0sp"
    android:visibility="invisible"
    app:layout_constraintTop_toTopOf="parent" />

And then use app:layout_constraintBaseline_toBaselineOf="@id/guideline" for aligning the other view to it.

I've found a workaround to align the text following exactly the Material Design guideline as mentioned by @robinst .

Firstly add an ImageView, with 0 as layout_width, your desired baseline as layout_height, no src and baselineAlignBottom set to true:

<ImageView
    android:id="@+id/typeTextBaseline"
    android:layout_width="0dp"
    android:layout_height="24dp"
    android:baselineAlignBottom="true"
    android:visibility="invisible"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

Then you can align your TextView's baseline to this ImageView's baseline:

<TextView
    android:id="@+id/typeTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="16dp"
    android:textAppearance="@style/TextAppearance.MaterialComponents.Overline"
    app:layout_constraintBaseline_toBaselineOf="@id/typeTextBaseline"
    app:layout_constraintStart_toStartOf="parent" />

I found this workaround when searching all implementations of View's getBaseline method, and the ImageView's implementation is as follow:

public int getBaseline() {
    if (mBaselineAlignBottom) {
        return getMeasuredHeight();
    } else {
        return mBaseline;
    }
}

So, once you set baselineAlignBottom to true, the ImageView's baseline becomes its bottom edge and it is magically served as a guideline now:)

Related