13

背景

我正在制作一个有一些设置的应用程序,我想使用内置的 PreferenceActivity 或 PreferenceFragment 来完成这项工作

问题

有些偏好的标题很长,我无法缩短,而且我认为如果我将应用程序本地化(翻译成多种语言),我会面临同样的问题(例如德语,有时单词很长)。

在这种情况下,您得到的只是文本的开头,然后是“...”(或更少的点,顺便说一句,这没有多大意义)。

例子:

在此处输入图像描述

我试过的

我知道 PreferenceActivity 是从 ListActivity 扩展而来的,所以我可以将它的适配器更改为我想要的任何东西,但这会删除它的工作方式。

我也知道我可以从偏好类的每种类型扩展,使用“onCreateView”方法来引用创建的视图,然后访问它的子视图,但这很奇怪,不是吗?我的意思是,这几乎就像假设它永远不会改变它的外观一样。

编辑:这是我尝试过的示例代码:

从每个偏好类扩展,并在每个偏好类中使用:

...
@Override
protected View onCreateView(final ViewGroup parent)
  {
  final View view=super.onCreateView(parent);
  ViewUtil.handlePreferenceTitleTextView(view);
  return view;
  }
...

//ViewUtil.java :

private void handlePreferenceTitleTextView(final View v)
  {
  final TextView titleTextView=(TextView)v.findViewById(android.R.id.title);
  if(titleTextView!=null)
    titleTextView.setSingleLine(false);
  }

它有效,但我不建议这样做,因为谷歌可能会改变偏好视图的工作方式。

问题

如何在 Android 上处理首选项标题中的长文本?

是否有可能让它有一个椭圆/选框(这样它就有一个动画来显示一切)?或者也许自动适应字体大小?或者将其设置为自动换行?或者一个允许用户滚动阅读其余文本的水平滚动视图?

是否有关于如何处理此类案件的约定?也许长按以显示吐司/对话框以查看整个文本?

4

4 回答 4

6

这是我针对特定情况SwitchPreference和一般偏好的问题的解决方案。

首先,我应该注意,对于 14 之前的 API 级别,默认情况下,偏好标题似乎是多行的——至少我没有看到 Android 2.3.3 中的长标题有任何问题。在较新版本的 Android 中,此行为已更改为强制单行标题。

解决方法是稍微调整一下SwitchPreference或任何其他类型的首选项布局。

在首选项屏幕文件中添加android:layout所需首选项的属性,例如:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
  <PreferenceCategory android:title="@string/prefs_category">
    <SwitchPreference
        android:key="keyOfThePreference"
        android:title="@string/pref_title"
        android:switchTextOn="@string/pref_on"
        android:switchTextOff="@string/pref_off"
        android:summaryOn="@string/pref_enabled"
        android:summaryOff="@string/pref_disabled"
        android:layout="@layout/preference_multiline"
        />
        ...

接下来,提供preference_multiline.xml替代布局。我使用了标准的修改版本preference.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- Layout for a Preference in a PreferenceActivity. The
     Preference is able to place a specific widget for its particular
     type in the "widget_frame" layout. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:gravity="center_vertical"
    android:paddingRight="?android:attr/scrollbarSize"
    android:background="?android:attr/selectableItemBackground" >

    <ImageView
        android:id="@+android:id/icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        />

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="15dip"
        android:layout_marginRight="6dip"
        android:layout_marginTop="6dip"
        android:layout_marginBottom="6dip"
        android:layout_weight="1">

        <TextView android:id="@+android:id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:singleLine="false"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:ellipsize="marquee"
            android:fadingEdge="horizontal" />

        <TextView android:id="@+android:id/summary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@android:id/title"
            android:layout_alignLeft="@android:id/title"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textColor="?android:attr/textColorSecondary"
            android:maxLines="4" />

    </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:gravity="center_vertical"
        android:orientation="vertical" />

</LinearLayout>

在这里,我故意android:singleLine将标题中的值TextView从更改truefalse。这可以完成工作。

于 2014-09-26T10:48:31.663 回答
2

根据此处此处的解决方案,如果有人愿意,这是一种为所有人设置它的方法:

abstract class BasePreferenceFragment : PreferenceFragmentCompat() {

    private fun applyOperationsForAllPreferences(preference: Preference) {
        // preference.isIconSpaceReserved = false //you can add this too, if you don't want icons space
        preference.isSingleLineTitle = false
        if (preference is PreferenceGroup)
            for (i in 0 until preference.preferenceCount)
                applyOperationsForAllPreferences(preference.getPreference(i))
    }

    override fun setPreferenceScreen(preferenceScreen: PreferenceScreen?) {
        preferenceScreen?.let { applyOperationsForAllPreferences(it) }
        super.setPreferenceScreen(preferenceScreen)
    }

}
于 2019-02-23T22:28:59.060 回答
1

2021:使用 androidx.preference 时(可能每个人都有)

你可以简单地使用app:singleLineTitle="false"

<Preference
        app:key="your_key"
        app:singleLineTitle="false"
        app:title="LONG TITLEEEEEEE EEEEEEEEE EEEEEEEEEEEEEEE" />

也适用于开关等

于 2021-04-30T17:03:22.820 回答
0

我不想复制粘贴布局,所以我最终将首选项子类化:

import android.content.Context;
import android.support.v7.preference.CheckBoxPreference;
import android.support.v7.preference.PreferenceViewHolder;
import android.util.AttributeSet;
import android.widget.TextView;

public class CustomCheckboxPreference extends CheckBoxPreference {

  public CustomCheckboxPreference(Context context) {
    super(context);
  }

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

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

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

  @Override
  public void onBindViewHolder(PreferenceViewHolder holder) {
    super.onBindViewHolder(holder);
    TextView title = (TextView) holder.findViewById(android.R.id.title);
    if (title != null) {
      title.setSingleLine(false);
    }
  }

}

然后只需在您的prefs.xml

<android.support.v7.preference.PreferenceScreen ...>
  <android.support.v7.preference.PreferenceCategory ...>
    <com.example.CustomCheckboxPreference
      ...
      />
于 2018-02-12T15:01:17.697 回答