Android AppCompat v21 provides SwitchCompat does not provide SwitchCompatPreference
Asked Answered
B

7

14

It seems AppCompat v21 provides SwitchCompat does not provide SwitchCompatPreference.

I know I can use SwitchPreference but it is not visually identical. On Android 4.x; when I use SwitchCompact from v21 on activity interface, it looks like material switch button, but, because there is no SwitchCompactPreference I have to use SwitchPreference in my preference view and obviously it has Android 4.0 look.

It looks like AppCompact v21 half complete.

Am I missing something?

Biddick answered 23/10, 2014 at 20:7 Comment(2)
In the same predicament. Hopefully someone finds a solution.Brigitte
I have answered the question here: #26725066Ahlgren
F
6

Here is a code snippet displaying material Switches even on older versions. https://gist.github.com/cgollner/5b31123c98b2c1cad8dc https://gist.github.com/cgollner/3c7fe2f9d34aee38bd0c

Reference: https://plus.google.com/118168530059850940658/posts/badausxo1J6

Forseti answered 25/2, 2015 at 15:37 Comment(0)
G
10

Based on the currently accepted answer, and cgollner's gist, if you only take the xml layout from there: https://gist.github.com/cgollner/3c7fe2f9d34aee38bd0c

And do this:

<CheckBoxPreference
            android:widgetLayout="@layout/preference_switch_layout"
            android:defaultValue="off"
            android:key="key1"
            android:title="@string/title1" />

Instead of this (adding the layout from source with setWidgetLayoutResource):

<com.cgollner.unclouded.preferences.SwitchCompatPreference
            android:defaultValue="off"
            android:key="key1"
            android:title="@string/title1" />

Then the animations will also work both on lollipop and below using the same xml.

Guiana answered 5/7, 2015 at 11:36 Comment(2)
It would be interesting to know why the animations work with this approach and why they do not work when you extend CheckBoxPreferences and call setWidgetLayoutResource(). But for whatever reason, this does seem to work, so +1.Impractical
This is a great solution. I'm also curious why setWidgetLayoutResource() doesn't work. I did a quick test and if we do android:widgetLayout="@layout/preference_switch_layout" with SwitchCompatPreference while commenting out the setWidgetLayoutResource() calls, it still doesn't work. It only works with CheckboxPreference.Gammy
H
6

I build a little something for myself, SwitchCompatPreference.java. Extending SwitchPreference turned out to be the easiest way to build this. Sadly, SwitchCompat doesn't inherit from Switch, so the original SwitchPreference requires a slight modification. The preference is used as follows:

<me.barrasso.android.volume.ui.SwitchCompatPreference
        android:icon="@drawable/icon"
        android:key="key"
        android:defaultValue="false"
        android:widgetLayout="@layout/pref_switch"
        android:title="@string/title"
        android:summary="@string/summary" />

The layout is super-simple, tweak it as needed.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.SwitchCompat
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/toggle"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:textIsSelectable="false"
    android:textStyle="bold" />
Hypothetical answered 19/12, 2014 at 18:16 Comment(0)
F
6

Here is a code snippet displaying material Switches even on older versions. https://gist.github.com/cgollner/5b31123c98b2c1cad8dc https://gist.github.com/cgollner/3c7fe2f9d34aee38bd0c

Reference: https://plus.google.com/118168530059850940658/posts/badausxo1J6

Forseti answered 25/2, 2015 at 15:37 Comment(0)
B
3

You're not going to like this answer but the best way I can think of is to create your own preference from the SwitchCompat object:

http://developer.android.com/guide/topics/ui/settings.html#Custom

I know this answer isn't the best, and there are no code samples yet. I will try to work on it over the weekend and update this answer with what I find.

Brigitte answered 31/10, 2014 at 17:21 Comment(0)
F
1

CONS: May not work on every device.


Use AppCompatDelegate in your PreferenceActivity (you can base off the class from AppCompatPreferenceActivity) and override the onCreateView to return SwitchCompat while creating a Switch view

i.e.,

public abstract class AppCompatPreferenceActivity extends PreferenceActivity {
    private AppCompatDelegate mDelegate;

    //... other methods omitted for clarity

    @Override
    public View onCreateView(String name, Context context, AttributeSet attrs) {
        // Allow super to try and create a view first
        final View result = super.onCreateView(name, context, attrs);
        if (result != null) {
            return result;
        }

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            switch (name) {
                // ... can add other views here
                case "Switch":
                    return new SwitchCompat(this, attrs);
            }
        }
        return null;
    }
}

The advantage is that, this way you can add support existing apps without changing your layouts, and minimal effort.

Frowsy answered 22/7, 2015 at 11:55 Comment(0)
M
1

This is about the animation for SwitchCompat widget in accepted answer.

I found that the problem is caused by a flag in Preference class, in Android 4.0-4.3, the flag is mHasSpecifiedLayout, in Android 4.4 the flag is mCanRecycleLayout.

When you set the widget using setWidgetLayoutResource, it will change this flag.

If you create a new customized preference class using different package name(except android.preference or com.android), it will also change this flag.

When mHasSpecifiedLayout is false or CanRecycleLayout is true, the animation will work, otherwise the animation does not work.

So you can set the widget layout using reflection instead of setWidgetLayoutResource() method, then the animation will not be broken.

Here is a snippet:

        CheckBoxPreference switchPref = new CheckBoxPreference(getActivity());
        try {
            Field field = Preference.class.getDeclaredField("mWidgetLayoutResId");
            field.setAccessible(true);
            field.setInt(switchPref, R.layout.preference_switch_layout);
        } catch (Exception e) {
            switchPref.setWidgetLayoutResource(R.layout.preference_switch_layout);
        }
        switchPref.setKey(key);
        switchPref.setTitle(titleRes);
        switchPref.setSummary(summaryRes);
        switchPref.setDefaultValue(defaultValue);
Miocene answered 4/10, 2015 at 9:28 Comment(0)
M
-2

From the official Android blog:

How do I use AppCompat with Preferences?
You can continue to use PreferenceFragment in your ActionBarActivity when running on an API v11+ device. For devices before that, you will need to provide a normal PreferenceActivity which is not material-styled.

Materfamilias answered 23/10, 2014 at 22:28 Comment(1)
I understand that. My question is about the look of SwitchPreference, not preference activityBiddick

© 2022 - 2024 — McMap. All rights reserved.