代码之家  ›  专栏  ›  技术社区  ›  android developer

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

  •  13
  • android developer  · 技术社区  · 11 年前

    出身背景

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

    这个问题

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

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

    例子:

    enter image description here

    我尝试过的

    我知道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 回复  |  直到 11 年前
        1
  •  6
  •   Stan    10 年前

    这是我针对 SwitchPreference 以及一般的偏好。

    首先,我应该注意到,对于14之前的API级别,首选项标题默认是多行的,至少我在Android 2.3.3中没有发现长标题有任何问题。在新版本的安卓系统中,这种行为已改为强制单行标题。

    解决方法是将 切换首选项 或者任何其他类型的偏好的布局。

    在首选项屏幕文件中添加 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 从…起 true false 。这就完成了任务。

        2
  •  2
  •   android developer    3 年前

    基于来自的解决方案 here here ,如果有人愿意,这是一种为所有人设置的方式:

    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)
        }
    
    }
    
        3
  •  1
  •   Merthan Erdem    3 年前

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

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

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

    也适用于交换机等

        4
  •  0
  •   Albert Vila Calvo    5 年前

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

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