Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing the highlight and title color for fragments in PreferenceActivity

I'm using the Material theme, and I'd like to change the color of the two marked areas in the image below - i.e. the highlight color (#1) and the color of the title in the details fragment (#2).

I know there's an attribute for the color of each somewhere in the theme, but I just can't seem to find it.

enter image description here

Any ideas?

like image 228
Michell Bak Avatar asked Nov 14 '14 04:11

Michell Bak


1 Answers

I know there's an attribute for the color of each somewhere in the theme, but I just can't seem to find it.

Item number 1

The attribute you'll want is activatedBackgroundIndicator.

As per the docs

Drawable used as a background for activated items.

Reason being

The layout used for each header item in a PreferenceActivity is preference_header_item_material which uses the activatedBackgroundIndicator as a background. You'll need a selector for this attribute, something like:

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_activated="true"><color android:color="yourColor" />
    </item>
    <item><color android:color="@android:color/transparent" />
    </item>

</selector>

Item number 2

This item is slightly trickier. It's not a PreferenceScreen like you suggested in the other answer, but the FragmentBreadCrumbs title. Unfortunately, the title color cannot be set using a theme because the attribute used to style it is private internal.

You can however set the text color using Reflection or just by traversing the breadcrumb's view hierarchy until you find the TextView used to display the title.

The layout used to display the content in each PreferenceActivity is preference_list_content_material which includes the breadcrumbs_in_fragment_material layout to display each breadcrumb. You can see from that layout that the id of each FragmentBreadCrums is android:id/title. Now we can use this id to find the breadcrumb and adjust the the TextView inside it.

Using Reflection

@Override
public void onBuildHeaders(List<Header> target) {
    super.onBuildHeaders(target);
    loadHeadersFromResource(R.xml.yourPreferenceHeaders, target);

    final View breadcrumb = findViewById(android.R.id.title);
    if (breadcrumb == null) {
        // Single pane layout
        return;
    }

    try {
        final Field titleColor = breadcrumb.getClass().getDeclaredField("mTextColor");
        titleColor.setAccessible(true);
        titleColor.setInt(breadcrumb, yourTitleColor);
    } catch (final Exception ignored) {
        // Nothing to do
    }

}

Traversing the view hierarchy

Using View.findViewsWithText is an easy way to handle this.

    breadcrumb.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {
            breadcrumb.getViewTreeObserver().removeOnGlobalLayoutListener(this);

            final ArrayList<View> outViews = Lists.newArrayList();
            breadcrumb.findViewsWithText(outViews, getString(R.string.your_header_title),
                    View.FIND_VIEWS_WITH_TEXT);

            ((TextView) outViews.get(0)).setTextColor(yourTitleColor);
        }

    });

Results

results

like image 89
adneal Avatar answered Sep 27 '22 03:09

adneal