Android Preference Fragment Text Color
Asked Answered
F

8

21

I want to change the text color in android preferences fragment. I am currently using a custom theme to change the checkbox image, background, onClick highlighting and it all works great...besides the text color. I don't want to use a default theme, I want to have my own theme so it all looks how I want to but just change the text color, can someone please help.

styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <style name="selectedTextStyle">  
        <item name="android:textSize">18sp</item>
    </style>
    <style name="buttonTextStyle">  
        <item name="android:textSize">20sp</item>
    </style>
    <style name="PreferencesTheme" >
        <item name="android:windowBackground">@drawable/lists_background</item>
        <item name="android:listViewStyle">@style/listViewPrefs</item>
        <item name="android:checkboxStyle">@style/MyCheckbox</item>

    </style>
    <style name="MyTextAppearance" parent="@android:style/TextAppearance">
        <item name="android:textColor">@color/black</item>
      </style>
    <style name="listViewPrefs" parent="@android:Widget.ListView">
        <item name="android:listSelector">@layout/list_selector_master</item>
        <item name="android:textAppearance">@style/MyTextAppearance</item>
    </style>
    <style name="MyCheckbox" parent="android:Widget.CompoundButton.CheckBox">
        <item name="android:button">@drawable/btn_check</item>
    </style>

</resources>

Manifest:

        <activity
            android:name="com.package.SettingsActivity"
            android:theme="@style/PreferencesTheme"
            android:configChanges="keyboard|orientation" >
        </activity>

Activity:

import android.app.Activity;
import android.os.Bundle;
import android.preference.PreferenceFragment;

public class SettingsActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Display the fragment as the main content.
        getFragmentManager().beginTransaction()
                .replace(android.R.id.content, new SettingsFragment())
                .commit();

    }
    public static class SettingsFragment extends PreferenceFragment {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            // Load the preferences from an XML resource
            addPreferencesFromResource(R.xml.preferences);

        }
    }

}
Fanfani answered 1/2, 2013 at 6:53 Comment(0)
U
13

Here are the two TextView objects from preference.xml (layout for a Preference):

    <TextView android:id="@+android:id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:singleLine="true"
        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" />

So looks like you can override textAppearanceLarge and textColorSecondary in your theme to achieve a color change. Here's an example:

<style name="AppTheme">
    <item name="android:textAppearanceLarge">@style/MyTextAppearance</item>
    <item name="android:checkboxStyle">@style/MyCheckBox</item>
</style>

<style name="MyCheckBox" parent="@android:style/Widget.CompoundButton.CheckBox">
    <item name="android:button">@android:drawable/btn_star</item>
</style>

<style name="MyTextAppearance" parent="@android:style/TextAppearance.Large">
    <item name="android:textColor">#ff0000</item>
</style>
Urethroscope answered 1/2, 2013 at 7:1 Comment(17)
I think that is it. Could you please help me do so, <item name="android:textAppearanceLarge">@style/MyTextAppearance</item> did not seem to do the trick.Fanfani
@Fanfani You placed it in the PreferenceTheme style?Urethroscope
Yes I did, the above line is from the PreferenceTheme and as you can see MyTextAppearance has textColor. Should I change it to something else?Fanfani
@Fanfani Isn't the color black by default? Try a different color.Urethroscope
No the color is light gray and it clashes with my background, I can barely see the text.Fanfani
@Fanfani Check my edit. I just created a new application to test this out and it worked for me.Urethroscope
First of all thank you! Second, I am trying to reproduce it and I can't. If i set PreferenceTheme to android:Theme.Light this changes text to black but then it gets rid of my custom checkbox and list view selector. If I don't set parent theme to light then nothing happens. (I believe the default color for Theme Light is black).Fanfani
Try setting the parent theme to android:Theme.BlackUrethroscope
Ok, so again, this does change the color of my text but it makes my action bar look old and overrides my listView selector colors. It goes to default ugly yellow selector.Fanfani
This is a bit difficult because you originally didn't define a parent theme for your custom theme, so I'm not sure where it's inheriting its values from. Without knowing that, I don't know where to look to find what style needs to be overridden.Urethroscope
Could I select Theme.Light and then override the selector that way and redefine the titlebar to system default? Would you know how to do that?Fanfani
I removed the parent from my theme and everything still works fine. I even changed the default check box the exact same way you did. So that should be working. I'll edit my answer again with how my theme looks now.Urethroscope
I still can't get it to work. I removed the background to try it and still nothing. I am updating my original with my SettingsActivity which uses a PreferenceFragment, could that be the issue?Fanfani
It looks fine to me. I'm not sure why it wouldn't work for you but work for me. Not sure what else to suggest. Sorry :(Urethroscope
Thank you so much for your time. If no one else answers Ill give you the answer credits.Fanfani
I ended up having to redefine android:textAppearanceMedium in order to change the text color of the preference title. I have zero understanding as to why this worked and not android:textAppearanceLarge.Ledesma
The holo preference layout, preference_holo.xml, uses textAppearance.Medium.Chancroid
N
10

I think an easy and clear way to do that is next:

res/values/styles.xml

<style name="SettingsFragmentStyle">

    <item name="android:textColorSecondary">#222</item>
    <item name="android:textColor">#CCC</item>
    <item name="android:background">#999</item>
    ...
</style>

In the Activity that contains PreferenceFragment subclass inside onCreate:

setTheme(R.style.SettingsFragmentStyle);
Nadda answered 16/4, 2015 at 23:57 Comment(1)
For me it was the textColorSecondary (and textColorPrimary) that made it work. Thanks for sharing!Lording
T
6

Just found an answer that gets the job done.

This file is default layout for the preference list item:

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2006 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<!-- 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="true"
            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>

You can use it as base and create your own custom layout. This layout must be applied within each Preference like this

<Preference android:key="somekey" 
android:title="Title" 
android:summary="Summary" 
android:layout="@layout/custom_preference_layout"/>

You can change the whole layout outside the list, you just need to have a layout file that contains a listview where the preferences will be populated like this:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Something" />

    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</LinearLayout>

To override the default layout for the PreferenceFragment, override the method onCreateView and change the inflated view:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.layout.custom_options_layout, null);
}

Based off these answers:

Creating a custom layout for preferences

How to add a button to PreferenceScreen

Android: How to adjust Margin/Padding in Preference?

Tyndall answered 17/7, 2013 at 22:44 Comment(1)
Since I can't mark my own answer as correct for the bounty I'm still accepting answers that achieve the same using only themes (what seems to be what the original poster wanted).Tyndall
T
2

To me nothing of the above methods didn't work. I ended up extending Prefernces class of the kind I used, in my case CheckBoxPrefernces:

 public class MyPreferenceCheckBox extends CheckBoxPreference {

    public MyPreferenceCheckBox(Context context) {
        super(context);
    }
    public MyPreferenceCheckBox(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public MyPreferenceCheckBox(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected View onCreateView(ViewGroup parent) {
        ViewGroup root = (ViewGroup) super.onCreateView(parent);
        ((TextView)root.findViewById(android.R.id.title)).setTextColor(parent.getResources().getColor(R.color.red));
        ((TextView)root.findViewById(android.R.id.summary)).setTextColor(parent.getResources().getColor(R.color.red));
        return root;
    }
}

And the use in the prefs.xml:

 <com.my.package.name.MyPreferenceCheckBox
        android:title="@string/my_title"
        android:defaultValue="true"
        android:key="@string/my_key"
        android:summary="On/Off" />

This answer showed me that path:

Tolliver answered 17/8, 2015 at 12:32 Comment(0)
I
1

Haven't got enough rep to comment or upvote, but I just wanted to add that mharper's suggestion about TextAppearanceMedium also worked for me in regards to changing the text colour. If somebody knows why this is, please do explain it.

So just adjust the accepted answer like so:

<style name="AppTheme">
     <item name="android:textAppearanceMedium">@style/MyTextAppearance</item>
</style>

<style name="MyTextAppearance" parent="@android:style/TextAppearance.Medium">
     <item name="android:textColor">#ff0000</item>
</style>

At least if nobody can explain why this is, it might stop somebody having the same difficulty I did trying to change the text colour.

Indue answered 30/4, 2014 at 14:53 Comment(1)
Your preferences are probably using preference_holo.xml, not preference.xml. The holo version uses textAppearance.Medium.Chancroid
C
1

I was able to change text color in PreferenceFragment with this:

styles.xml

<resources>

    <style name="SettingsTheme" parent="android:Theme.Holo">
        <item name="android:textColorPrimary">@color/light_blue_font_color</item>
        <item name="android:textColorSecondary">@color/white_font_color</item>
        <item name="android:textColorTertiary">@color/white_font_color</item>
    </style>

</resources>

colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="light_blue_font_color">#33b5e5 </color>
    <color name="white_font_color">#ffffff </color>
</resources>

AndroidManifest.xml

<activity
    android:name="xx.yy.zz.SettingsActivity"
    android:theme="@style/SettingsTheme" >
</activity>
Commination answered 7/7, 2014 at 17:46 Comment(0)
M
0

If you're using compat library, just add:

<item name="colorAccent">#ff0000</item>

to your style

Monaghan answered 25/1, 2015 at 12:24 Comment(0)
M
-1

I work with min API 11 and compile whith 23. set theme and after set background for this theme. if you work with > API 14 you can use Theme_DeviceDefault.

This is the simplest solution I find :

public static class SettingsFragment extends PreferenceFragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        getActivity().setTheme(android.R.style.Theme_Holo);
        // Load the preferences from an XML resource
        addPreferencesFromResource(R.xml.settings);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        if(view != null){
            view.setBackgroundColor(ContextCompat.getColor(getActivity(), android.R.color.background_dark));
        }
    }
}
Multiform answered 16/6, 2016 at 9:26 Comment(1)
Careful with this, is just reset the entire theme on the activity. Meaning when you display another fragment it will have this same theme.Jennettejenni

© 2022 - 2024 — McMap. All rights reserved.