在约束布局中将TextView的基线对齐到参考线的方法

5

希望我不是太笨了,但我无法将TextView的基线与ConstraintLayout中的Guideline对齐。看起来Guideline没有基线,这非常烦人。有没有人知道我该如何实现这个呢?这里有一些布局xml代码,它不能正常工作:

                 <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" />

你的布局会如何展示?你想要实现什么目标? - KuLdip PaTel
3个回答

5

我在按照Material Design实现一个两行列表时遇到了这个问题,其中“双行项目”应该与顶部的基线相距32dp:

Material Design spec

看起来像普通的ViewGuideline没有基线,因为从getBaseline返回-1。所以最终我使用了一个不可见的TextView,就像这样:

<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" />

然后使用app:layout_constraintBaseline_toBaselineOf="@id/guideline"将另一个视图与它对齐。


2

我想我可能找到了一个解决方案。我尝试扩展Baseline并从“getBaseline”返回0,但从未被调用。所以我尝试扩展AppCompatButton并从“getBaseline”返回“getMeasuredHeight”(就像ImageView在使用“baselineAlignBottom”时所做的那样),现在似乎可以正确地工作了。TextView只需要更改以将其基线与按钮对齐,而不是基准线。我需要使用类似于ImageView的属性进行清理,但目前这就是我得到的结果:

public class ButtonBottomBaseline extends android.support.v7.widget.AppCompatButton {
    public ButtonBottomBaseline(Context context) {
        super(context);
    }

    public ButtonBottomBaseline(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ButtonBottomBaseline(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public int getBaseline() {
        return getMeasuredHeight();
    }
}

0

我已经找到了一个解决方案,可以按照@robinst提到的Material Design准则精确地对齐文本。

首先添加一个ImageView,将layout_width设置为0,将所需的基线设置为layout_height,不设置src,并将baselineAlignBottom设置为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" />

然后,您可以将TextView的基线与此ImageView的基线对齐:

<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" />

在查找View的getBaseline方法的所有实现时,我发现了这个解决方法,ImageView的实现如下:

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

所以,一旦你将baselineAlignBottom设置为true,ImageView的基线就变成了它的底部边缘,现在它神奇地作为一个指导线:)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接