【问题标题】:How to wrap a preference title? (Really)如何包装首选项标题? (真的)
【发布时间】:2013-11-06 03:07:02
【问题描述】:

请不要将我指向 How to wrap preference title?,因为它不适用于(正如我评论的)您使用 @strings/ 引用 strings.xml 文件的情况。

如果你使用

android:title="@string/some_string"

然后放

<string name="some_string">the string I want \n to wrap</string>

进入 strings.xml\n 被忽略。

【问题讨论】:

标签: android android-preferences


【解决方案1】:

对于大多数 Android 版本,没有公开的 API 允许在 Preference 标题上换行。这导致了中长标题上的文本被截断/褪色的不幸常见错误,尤其是在纵向的小屏幕设备上:

&ltPreferenceScreen
    android:key="my_pref_key"
    android:title="A Long Preference Title that should wrap to multiple lines" />

但是有两种方法可以解决它:

1.简单的方法 - 但这仅适用于 Android 8 (API 26) 及更高版本:

像这样使用android:singleLineTitle="false"

&ltPreferenceScreen
    android:key="my_pref_key"
    android:title="A Long Preference Title that should wrap to multiple lines"
    android:singleLineTitle="false" />

2。艰难的方式 - 自定义偏好子布局 - 这适用于所有 Android 版本:

对于标题较长的首选项,请在其上使用自定义布局 (like this),其中TextView 已明确关闭单行文本。但是您必须以编程方式设置布局,因为 Android 4(Holo 主题)和 Android 5 及更高版本(Material 主题)的主题不同。

SettingsFragment.javaSettingsActivity.java:

PreferenceScreen myPreferenceItem = (PreferenceScreen)
    getPreferenceScreen().findPreference("my_pref_key");

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    myPreferenceItem.
        setLayoutResource(R.layout.preference_child_material_customized);
} else {
    myPreferenceItem.
        setLayoutResource(R.layout.preference_child_holo_customized);
}

res/layout/preference_child_material_customized.xml: 的示例

从您的 Android SDK/platforms/android-22/data/res/layout/ 复制此文件 preference_child_material.xml (like this one) 并对其进行自定义:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="?android:attr/listPreferredItemPaddingStart"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:gravity="center_vertical"
    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">

    <LinearLayout
        android:id="@+android:id/icon_frame"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:minWidth="40dip"
        android:gravity="start|center_vertical"
        android:orientation="horizontal">
        <ImageView
            android:id="@+android:id/icon"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dip" />
    </LinearLayout>

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:paddingTop="16dip"
        android:paddingBottom="16dip">

        <TextView android:id="@+android:id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:singleLine="false"
            android:textAppearance="?android:attr/textAppearanceListItem" />

        <TextView android:id="@+android:id/summary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@android:id/title"
            android:layout_alignStart="@android:id/title"
            android:textAppearance="?android:attr/textAppearanceListItemSecondary"
            android:textColor="?android:attr/textColorSecondary"
            android:maxLines="10" />

    </RelativeLayout>

    <!-- Preference should place its actual preference widget here. -->
    <LinearLayout android:id="@+android:id/widget_frame"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:minWidth="58dip"
        android:gravity="end|center_vertical"
        android:orientation="vertical" />

</LinearLayout>

注意 TextView 上的 android:singleLine="false" 行。

对于res/layout/preference_child_holo_customized.xml,你应该从你的Android SDK/platforms/android-19/data/res/layout/复制它 preference_child.xmlpreference_child_holo.xml (like this one) 并以类似的方式对其进行自定义。

【讨论】:

  • 它需要 API 26 - 而不是 API 27。
  • 很遗憾,它不适用于CheckBoxPreference
  • @Dmitry 我已将其更正为 API 26,谢谢。我不知道如何为 CheckBoxPreference 修复它。
  • @galaxigirl 我相信它确实适用于ListPreference。在 Android 8 及更高版本上,您应该使用android:singleLineTitle="false"。在 Android 7 及更低版本上,您必须使用自定义布局,例如 android:layout="@layout/preference_child_material_without_icon" - 这是与 preference_child_material_customized.xml 类似的布局,但您应该删除包含图标的 LinearLayout 块。
  • @Mr-IDE 我在 API 28 上对其进行了测试 - 常规 Preference 已包装,ListPreference 为椭圆形
【解决方案2】:

我认为偏好屏幕内的所有titles 都应该是单行
我认为声明为android:title="The title of this preference\nis this." 行不通。这也会忽略\n

所以,我的建议是,把标题单行,做一个总结来描述它。

<CheckBoxPreference android:key="extention"
    android:title="@string/title"
    android:summary="@string/summary"
    android:defaultValue="true"
    />

注意:\n 将用于摘要

【讨论】:

  • 确实,它也不适用于没有@string/... 引用的字符串。我需要这个总是在标题末尾加上一个(experimental)。它也将在(已经存在的)摘要结束时完成它的工作。谢谢。
  • 但在摘要中我想通过 %s 显示所选值。 xml 中是否存在与字符串 (@string/summary) 连接的摘要 %s 中显示的内容?
  • 这可能不是公认的答案。您的解决方案排除了android:summary 的真正目的。有实现这一目标的实际解决方案吗?
【解决方案3】:

您可以将app:singleLineTitle="false"androidx.preference:preference 一起使用,例如:

<SwitchPreferenceCompat
        app:defaultValue="false"
        app:iconSpaceReserved="false"
        app:key="important_switch"
        app:singleLineTitle="false"
        app:title="@string/pref_switch_title" />

【讨论】:

  • 对我来说,singleLineTitle在我使用SwitchPreference时生效,但在我使用SwitchPreferenceCompat时没有。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-07
  • 2013-01-17
  • 2015-01-20
  • 2011-09-11
  • 1970-01-01
相关资源
最近更新 更多