Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwitchPreferenceCompat: android:switchTextOff / switchTextOn doesn't work

I'm trying to display a switchPreference which allows the user to display the distance according to miles or kms. I'm using the SwitchPreferenceCompat support library. According to the library, I can use the textSwitchOff and textSwitchOn to add text to the switch. I just want to add "km" or "miles" to my switch so that the user knows which metric is displayed.

According to this doc, all I need is the code below:

<android.support.v7.preference.PreferenceCategory
    android:layout="@layout/preferences_category"
    android:title="Distance" >

    <android.support.v7.preference.SwitchPreferenceCompat android:title="KM or Miles"
        android:key="kmormiles"
        android:switchTextOff="miles"
        android:switchTextOn="km"
        android:defaultValue="true"/>

</android.support.v7.preference.PreferenceCategory>

However, the switch just looks like a normal switch, there is no extra text on the switch itself.

enter image description here

How do I get it to display with the textOn and textOff?

I also tried the following:

    addPreferencesFromResource(R.xml.preferences);
    kmormiles = (SwitchPreferenceCompat) findPreference("kmormiles");
    kmormiles.setSwitchTextOff("Km");
    kmormiles.setSwitchTextOn("miles");

Still doesn't work. I'm trying it on two different genymotion emulators, API 16 and API 21.

like image 201
Simon Avatar asked Feb 15 '16 17:02

Simon


1 Answers

Because of SwitchPreferenceCompat using a SwitchCompat widget by default, Android Switch widget textOn and textOff not working in Lollipop has an application here as well. And the first statement

Text is not shown by default under Material theme since the switch widget assets don't work well with text.

also explains, why the result doesn't look good at all.

The SwitchPreferenceCompat class itself doesn't provide a possibility to set whether the on/off text should be displayed. So one way to make it work could be overriding the onBindViewHolder(PreferenceViewHolder) method to set it programmatically.

Another and maybe better method is utilization of the theming mechanisms you're forced to use with the preference compat library anyway. You can't set any attribute to the views directly, but you can define the layout to be used with android:widgetLayout. So just create your own preference theme overlay

<style name="MyPreferenceThemeOverlay" parent="PreferenceThemeOverlay">
    <item name="switchPreferenceCompatStyle">@style/MySwitchPreferenceCompat</item>
</style>

with your own switch preference style

<style name="MySwitchPreferenceCompat" parent="Preference.SwitchPreferenceCompat">
    <item name="android:widgetLayout">@layout/pref_stack</item>
</style>

using the slightly modified default switch layout

<android.support.v7.widget.SwitchCompat
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/switchWidget"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@null"
    android:clickable="false"
    android:focusable="false"
    app:showText="true" />

Another thing you should keep in mind with your code is the compat functionality itself. With using android.support.v7.preference.SwitchPreferenceCompat explicitly, you'll never get versions more suitable for newer devices the inflater knows about automatically like the currently only available alternative android.support.v14.preference.SwitchPreferenceCompat. This might involve a little more work on your side though.

EDIT: This is the results of implementing the above suggestion by the poster, as he mentioned correctly, the results do not look good at all:

enter image description here

enter image description here

like image 127
tynn Avatar answered Nov 10 '22 03:11

tynn