It seems AppCompat v21 provides SwitchCompat does not provide SwitchCompatPerefrence.
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 pereference view and obviously it has Android 4.0 look.
It looks like AppCompact v21 half complete.
Am I missing something?
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
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.
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" />
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.
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.
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);
From the official Android blog:
How do I use AppCompat with Preferences?
You can continue to usePreferenceFragment
in yourActionBarActivity
when running on an API v11+ device. For devices before that, you will need to provide a normal PreferenceActivity which is not material-styled.
来源:https://stackoverflow.com/questions/26536509/android-appcompat-v21-provides-switchcompat-does-not-provide-switchcompatperefre