自定义PreferenceCategory标题

33

我有一个简单的偏好设置屏幕,定义如下:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory android:title="Security">
        <CheckBoxPreference 
            android:title="Require Pin on Start"
            android:summary="Require pin to run the application"
            android:key="@string/pref_require_pin"
            android:defaultValue="false" />
    </PreferenceCategory>

    <PreferenceCategory android:title="Settings">
        <ListPreference
           android:title="History Age (in days)"
           android:summary="Display items up to 30 days old"
           android:key="@string/pref_history_days"
           android:defaultValue="30"
           android:entries="@array/days_list"
           android:entryValues="@array/days_list"
           android:dialogTitle="Select History Age"/>
    </PreferenceCategory>
</PreferenceScreen>

我已经有一个样式设置,并在我的应用程序的其他地方使用过。

<style name="ListHeader">
    <item name="android:textColor">#000000</item>
    <item name="android:textStyle">bold</item>
    <item name="android:textSize">12sp</item>
    <item name="android:background">#cccccc</item>
    <item name="android:paddingTop">6px</item>
    <item name="android:paddingBottom">6px</item>
    <item name="android:paddingLeft">12px</item>
</style>

这是我的活动

public class PreferencesActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        addPreferencesFromResource(R.layout.preferences);
    }
}

如何将我的自定义样式应用于PreferenceCategory的标题?

4个回答

58

你应该查看Preference.Category样式:

<style name="Preference.Category">
    <item name="android:layout">@android:layout/preference_category</item>
   <item name="android:shouldDisableView">false</item>
   <item name="android:selectable">false</item>
</style>

我们来看一下 preference_category.xml 文件:

<!-- Layout used for PreferenceCategory in a PreferenceActivity. -->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    style="?android:attr/listSeparatorTextViewStyle"
    android:id="@+android:id/title"
/>

所以您需要创建一个自定义主题,继承默认的Android Theme 并将listSeparatorTextViewStyle的值覆盖为 ListHeader 样式。然后将此主题应用于继承了PreferenceActivity的Activity。


下面是如何实现:

首先,在您的styles.xml文件中添加以下代码:

<style name="PreferenceListHeader" 
       parent="@android:style/Widget.TextView.ListSeparator">

    <item name="android:textColor">#000000</item>
    <item name="android:textStyle">bold</item>
    <item name="android:textSize">12sp</item>
    <item name="android:background">#cccccc</item>
    <item name="android:paddingTop">6px</item>
    <item name="android:paddingBottom">6px</item>
    <item name="android:paddingLeft">12px</item>
</style>

<style name="Theme.Custom" parent="@android:style/Theme">
    <item name="android:listSeparatorTextViewStyle">@style/PreferenceListHeader</item>               
</style>

然后在你的AndroidManifest.xml文件中为你想要的活动添加主题:

 <activity android:name=".MyPreferencesActivity" 
           android:theme="@style/Theme.Custom" 
           ... >
 ...
 </activity>

以下是一张屏幕截图:

在此输入图片描述


3
你不必使用样式,只需在PreferenceCategory上使用android:layout属性即可。 - Nathan Schwermann
9
我遇到了“@android:style/Widget.TextView.ListSeparator”的问题,所以我用“@android:attr/listSeparatorTextViewStyle”替换了它。不要忘记定义layout_height和layout_width。 - joshas
6
获取父项时出错:找不到与给定名称@android:style/Widget.TextView.ListSeparator匹配的资源。 - Marcin S.
可以像上面所说的那样使用@android:attr/listSeparatorTextViewStyle。 - An-droid
3
这个回答已经不再适用了。android:style/Widget.TextView.ListSeparator已经不存在,而且android:attr/listSeparatorTextViewStyle也不存在。如果你尝试按照这个解决方案中的步骤,但选择任何现有的样式使其编译通过,应用程序将会崩溃。我无法相信这个问题变得如此混乱。 - Stevey
显示剩余6条评论

19

虽然@inazaruk已经回答得足够好了,但是最近的更新中(ADT 18及以上版本),styles有一些限制并导致错误。

Error retrieving parent for item: No resource found that matches the given name '@android:style/Widget.TextView.ListSeparator'.

查看此链接以了解问题及其解决方案。由于此帖子没有提供代码以便理解,因此我在此提供我的代码。

 <style name="Widget.TextView.ListSeparator" parent="@android:style/Widget.TextView">
    <item name="android:layout_width">match_parent</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:textStyle">bold</item>
    <item name="android:textSize">14sp</item>
    <item name="android:gravity">center_vertical</item>
</style>

<style name="PreferenceListHeader" parent="Widget.TextView.ListSeparator">
    <item name="android:textColor">#000000</item>
    <item name="android:textStyle">bold</item>
    <item name="android:textSize">18sp</item>
    <item name="android:background">#cccccc</item>
    <item name="android:paddingTop">6dp</item>
    <item name="android:paddingBottom">6dp</item>
    <item name="android:paddingLeft">12dp</item>
</style>

<style name="PreferenceScreen" parent="android:Theme.NoTitleBar">
    <item name="android:listSeparatorTextViewStyle">@style/PreferenceListHeader</item>
    <item name="android:background">#F2B1DBF3</item>
</style>

2
谢谢更新。我刚在API 19级别遇到了这个确切的问题! - Robert Hui
我没有看到任何分隔线? - Muhammad Babar
我有同样的问题。我不再看到偏好类别的分隔线。我该如何启用它? - NSouth
理论上,您应该能够指定自己的布局并将任何想要的内容放入其中(一行或其他任何内容)。但实际上,它似乎不起作用,被忽略了。 - Gábor
2
请注意,Lollipop在首选项和类别方面使用不同的样式。请查看https://github.com/android/platform_frameworks_base/blob/lollipop-mr1-release/core/res/res/values/styles_material.xml#L57 - Vadim Kotov
这段代码将无法编译,因为 Widget.TextView.ListSeparator 现在是私有的。这个答案很有帮助:https://dev59.com/XZjga4cB1Zd3GeqPPMYO#38279736 - Tina

15

按照inazaruk的回答所描述的方式进行样式设置非常简单,但它仅更改标题中文本的样式,不能指定全新的布局(样式将不适用于layout项目)。但是,如果您扩展类,则有一个简单的解决方案:

public class MyPreferenceCategory extends PreferenceCategory {

  public MyPreferenceCategory(Context context) {
    super(context);
    setLayoutResource(R.layout.yourlayout);
  }

  public MyPreferenceCategory(Context context, AttributeSet attrs) {
    super(context, attrs);
    setLayoutResource(R.layout.yourlayout);
  }
}

当定义您的首选项布局时,可以使用此代码替换原始的PreferenceCategory

您的布局可以包含任何您喜欢的内容,包括文本上方或下方的线条、不同的背景、填充等等。例如,这将显示带有线条的材料设计彩色副标题:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >
    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_marginTop="6dp"
        android:background="?attr/divider_color" />
    <TextView
        android:id="@+android:id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:padding="12dp"
        android:textColor="?attr/colorAccent"
        android:textSize="14sp"
        android:textStyle="bold" />
</LinearLayout>

只有那个答案对我有用(使用AppCompat的目标API 21)。 - lujop

11

像Gábor的回答一样,但不是扩展PreferenceCategory,而是可以这样做: 1. 制作你的自定义布局。我将其命名为preference_category.xml

像 Gábor 的回答一样,但是不要扩展 PreferenceCategory ,可以通过以下方式实现: 1. 制作您的自定义布局。我将其命名为 preference_category.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<View
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:layout_marginTop="6dp"
    android:background="?attr/divider_color" />
<TextView
    android:id="@+android:id/title"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:padding="12dp"
    android:textColor="?attr/colorAccent"
    android:textSize="14sp"
    android:textStyle="bold" />
</LinearLayout>

重要提示: 布局必须包含一个id为android:id="@+android:id/title"的文本视图。

2. 在preference中添加以下行:android:layout="@layout/preference_category"

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >

<PreferenceCategory
    android:key="Font_Settings"
    android:title="@string/UISetting"
    android:layout="@layout/preference_category" >
... //  other preferences in the category
</PreferenceCategory>
</PreferenceScreen>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接