多行文本视图与其基线对齐(ConstraintLayout Android Studio)

Tia*_*tos 16 android alignment multiline android-constraintlayout

我有三个TextViews "hi""x""Hello World"我想在Hello World文本底部对齐(即hi_x_World)。你好世界仅仅是一个线,但两者layout_widthlayout_height设置为wrap_content

它们具有不同的字体大小,因此即使我可以轻松对齐文本视图框的底部,文本本身也不会对齐。

我发现了一个不同的 XML 参数app:layout_constraintBaseline_toBaselineOf="@+id/text,它在 TextView 中只有一行时有效。但是,当我有 2 行或更多行(如在 Hello World TextView 中)时,考虑的基线在“Hello”而不是“World”中。

有什么方法可以更改设置以考虑单词“World”而不是“Hello”下方的基线?

在此处输入图片说明

Che*_*amp 8

第二个更新:这是查看从这个Stack Overflow 答案中获取的第一个解决方案的另一种方式,该解决方案也适用于ConstraintLayout。此解决方案使用自定义TextView。自定义的TextView返回文本的最后一行的基线的TextViewgetBaseline()函数,而不是这是默认动作第一行的基线。这是一个很好的、干净的解决方案 (IMO),它考虑了多行TextViews以及重力等。

BaselineLastLineTextView 的 Kotlin 版本

class BaselineLastLineTextView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null
) : AppCompatTextView(context, attrs) {

    override fun getBaseline(): Int {
        val layout = layout ?: return super.getBaseline()
        val baselineOffset = super.getBaseline() - layout.getLineBaseline(0)
        return baselineOffset + layout.getLineBaseline(layout.lineCount - 1)
    }
}
Run Code Online (Sandbox Code Playgroud)

第一次更新:这是对我下面的答案的更新,它仍然是一个有效的解决方案 (IMO)。这是一种替代方法,不涉及任何 Java/Kotlin 代码,只需使用 XML 即可完成。

创建一个不可见的wrap_content TextView,其字体大小与“Hello World!”相同。文本视图。(根据实际布局,您可能还需要考虑填充和边距。)将这个新视图限制在“Hello World!”的底部,制作它invisible并将内容设置为保证仅占一行的简短内容。这将为您提供一个目标视图,该视图与“Hello World!”的最后一行具有相同的基线。看法。

将“hi”和“x”的基线约束到新invisible视图。所有视图现在将共享相同的基线并且无需编码。

在此处输入图片说明

<androidx.constraintlayout.widget.ConstraintLayout 
    android:id="@+id/layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/hiddenView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="A"
        android:textSize="50sp"
        android:visibility="invisible"
        app:layout_constraintBottom_toBottomOf="@id/helloView"
        app:layout_constraintEnd_toEndOf="parent" />

    <TextView
        android:id="@+id/hiView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="hi"
        android:textSize="46sp"
        app:layout_constraintBaseline_toBaselineOf="@id/hiddenView"
        app:layout_constraintEnd_toStartOf="@+id/xView"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@id/helloView" />

    <TextView
        android:id="@+id/xView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="x"
        android:textSize="36sp"
        app:layout_constraintBaseline_toBaselineOf="@id/hiddenView"
        app:layout_constraintEnd_toStartOf="@+id/helloView"
        app:layout_constraintStart_toEndOf="@+id/hiView"
        app:layout_constraintTop_toTopOf="@id/helloView" />

    <TextView
        android:id="@+id/helloView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello\nWorld!"
        android:textSize="50sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/xView"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:onClick="onClick"
        android:text="Adjust Base Lines"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/helloView" />


</androidx.constraintlayout.widget.ConstraintLayout>
Run Code Online (Sandbox Code Playgroud)

第一个答案:如另一个答案中所述,仅使用ConstraintLayout约束无法做到这一点。您将需要求助于程序化解决方案。

每个TextView 中都有一个StaticLayout,它可以揭示一些关于文本排版的信息。通过参考静态布局,可以在适当的视图中添加填充以使基线对齐。

在这个演示中,三个TextViews只是将它们的顶部对齐。最初,视图如下所示:

在此处输入图片说明

单击按钮时,将计算基线位置并将填充添加到 "hi" 和 "x" TextViews的顶部。

在此处输入图片说明

细节会因实现而异,但这是通用技术。

主活动.kt

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    fun onClick(view: View) {
        button.isEnabled = false
        // Get the StaticLayout from the TextView
        val layout = helloView.layout

        // Get the base line location for last line of Hello World! TextView, "hi" and "x"
        val helloBaseLIne = layout.getLineBaseline(layout.lineCount - 1)
        val hiBaseLine = hiView.layout.getLineBaseline(0)
        val xBaseLine = xView.layout.getLineBaseline(0)
        
        // Shift "hi" and "x" down so base lines match that of hello world!
        hiView.updatePadding(top = helloBaseLIne - hiBaseLine)
        xView.updatePadding(top = helloBaseLIne - xBaseLine)
    }
}
Run Code Online (Sandbox Code Playgroud)

活动_main.xml

<androidx.constraintlayout.widget.ConstraintLayout 
    android:layout_width="match_parent"
    android:id="@+id/layout"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/hiView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="hi"
        android:textSize="46sp"
        app:layout_constraintTop_toTopOf="@id/helloView"
        app:layout_constraintEnd_toStartOf="@+id/xView"
        app:layout_constraintStart_toStartOf="parent"/>

    <TextView
        android:id="@+id/xView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="x"
        android:textSize="36sp"
        app:layout_constraintTop_toTopOf="@id/helloView"
        app:layout_constraintEnd_toStartOf="@+id/helloView"
        app:layout_constraintStart_toEndOf="@+id/hiView" />

    <TextView
        android:id="@+id/helloView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello\nWorld!"
        android:textSize="50sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/xView"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:text="Adjust Base Lines"
        android:onClick="onClick"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/helloView" />


</androidx.constraintlayout.widget.ConstraintLayout>
Run Code Online (Sandbox Code Playgroud)