Android 当系统字体放大时 TextView 不换行内容

Android TextView not wrapping content when system wide font scaled larger

在我的应用程序中,我正在尝试调整此布局,以便当用户在 Android 系统设置 -> 显示 -> 字体大小(或某些设备的辅助功能设置)中缩放系统范围的字体大小时,它是可读的设备)。进行一些挖掘后,我发现这会将设备配置字体比例 (getResources().getConfiguration.fontScale) 从 1.0 调整为 1.15

我在 LinearLayout 中遇到一些奇怪的行为,其中一个 TextView 的宽度被压扁,当它设置为 wrap_content 时,也没有反映设置 minWidth.

平时的样子 字体缩放后的样子

这是有问题的 LinearLayout(在屏幕截图中为上下文添加的评论)

    <LinearLayout
        android:id="@+id/sectionPaintStatus"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="20dp"
        android:layout_marginTop="20dp"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <!-- () 6 Paint Items -->
        <LinearLayout
            android:id="@+id/sectionPaintItemToggle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:clipToPadding="false"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:paddingBottom="5dp">

            <android.support.design.widget.FloatingActionButton
                android:id="@+id/fabExpandPaintItems"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="5dp"
                android:rotation="180"
                android:src="@drawable/ic_collapse"
                app:elevation="2dp"
                app:fabSize="mini"/>

            <TextView
                android:id="@+id/tvPaintItemCount"
                style="@style/Label"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="5dp"
                android:text="0 Paint Items"
                android:textSize="16sp"/>

            <ImageView
                android:id="@+id/imgPaintAreaWarning"
                android:layout_width="20dp"
                android:layout_height="match_parent"
                android:layout_marginStart="10dp"
                android:scaleType="centerInside"
                android:src="@drawable/ic_edit_warning2"
                android:visibility="invisible"/>

        </LinearLayout>

        <!-- Inner layout to consume middle width and right align the rest -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="end"
            android:orientation="horizontal">

            <LinearLayout
                android:id="@+id/layoutPaintItemCount"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="end"
                android:orientation="vertical"
                android:visibility="invisible">

                <TextView
                    android:id="@+id/tvPaintItemCountStatus"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="2"
                    android:textSize="16sp"
                    android:textStyle="bold"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Paint Items"
                    android:textSize="16sp"/>

            </LinearLayout>

            <ImageView
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:layout_marginStart="30dp"
                android:scaleType="centerInside"
                android:src="@drawable/ic_time"/>

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="end"
                android:orientation="vertical">

                <TextView
                    android:id="@+id/tvPaintTime"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="2.5h"
                    android:textSize="16sp"
                    android:textStyle="bold"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Time"
                    android:textSize="16sp"/>

            </LinearLayout>

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="30dp"
                android:layout_marginEnd="30dp"
                android:minWidth="70dp"
                android:gravity="end"
                android:orientation="vertical">

                <TextView
                    android:id="@+id/tvPaintTotal"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="3.22"
                    android:textSize="16sp"
                    android:textStyle="bold"/>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Total"
                    android:textSize="16sp"/>

            </LinearLayout>
        </LinearLayout>
    </LinearLayout>

为什么最后 LinearLayout 包含 2 TextView 的内容没有正确包装?我尝试删除导致任何问题的 minWidth incase 并得到相同的结果。我不明白为什么所有其他布局都正确地包装了它们的内容,但最后一个却没有。

是否可以为缩放的系统宽字体添加资源文件夹?

Edit 似乎删除边距允许 TextView 包裹适当的宽度,但显然我需要边距。

谁能解释这种奇怪的行为?

编辑已解决 结果我完全忘记了布局中 "Paint Items" 标签和时间图标之间的一个不可见元素。这导致我 运行 超出水平方向 space。

您似乎使用了 layout_width="match_parent"gravity="end" 来对齐您的元素。

假设 在小型设备(或大文本)上,您希望“0 Paint Items”在不够 space 时椭圆化,并让'Time' 和 'Total' 字段以全宽显示。

为此,我们进行了以下更改:

首先,使 sectionPaintItemToggle 具有 0dp 宽度和 layout_weight="1" - 这告诉 Android "this should fill as much space is available".

<LinearLayout
    android:id="@+id/sectionPaintItemToggle"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    ... >

我删除了全部 gravity="end" 设置。

我将 "inner layout"(根据评论)更改为 wrap_content 宽度。

我删除了整个 layoutPaintItemCount 布局 - 我觉得您正在尝试一种不同的方式来进行 "N paint items" 布局。

最后,我们得到了这样的结果(我将 ImageView 换成了 FAB,并且只使用了我已有的资源——我想我也改变了一些边距):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:id="@+id/sectionPaintStatus"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginEnd="20dp"
    android:layout_marginStart="20dp"
    android:layout_marginTop="20dp"
    android:gravity="center_vertical"
    >

    <!-- () 6 Paint Items -->
    <LinearLayout
        android:id="@+id/sectionPaintItemToggle"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:clipToPadding="false"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        android:paddingBottom="5dp">

        <ImageView
            android:id="@+id/fabExpandPaintItems"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_margin="5dp"
            android:rotation="180"
            android:src="@drawable/ic_edit_black_24dp"/>

        <TextView
            android:id="@+id/tvPaintItemCount"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="5dp"
            android:text="0 Paint Items"
            android:textSize="16sp"/>

        <ImageView
            android:id="@+id/imgPaintAreaWarning"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_marginStart="10dp"
            android:scaleType="centerInside"
            android:src="@drawable/ic_edit_black_24dp"
            android:visibility="invisible"/>

    </LinearLayout>

    <!-- Inner layout to consume middle width and right align the rest -->
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <ImageView
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:scaleType="centerInside"
            android:src="@drawable/ic_edit_black_24dp"/>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:id="@+id/tvPaintTime"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="2.5h"
                android:textSize="16sp"
                android:textStyle="bold"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Time"
                android:textSize="16sp"/>

        </LinearLayout>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="30dp"
            android:layout_marginStart="30dp"
            android:orientation="vertical">

            <TextView
                android:id="@+id/tvPaintTotal"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="3.22"
                android:textSize="16sp"
                android:textStyle="bold"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Total"
                android:textSize="16sp"/>

        </LinearLayout>
    </LinearLayout>
</LinearLayout>

关键部分是让 Android 相信 "N Paint Items" 视图是您要缩小的视图。