cmparts: Use the preferences support library
* So we can mimic Settings exactly
Change-Id: I87bed4794df983c6e3f8c6c80dfd4de2debf9358
diff --git a/Android.mk b/Android.mk
index 0ffb101..07894b5 100644
--- a/Android.mk
+++ b/Android.mk
@@ -4,10 +4,36 @@
LOCAL_PACKAGE_NAME := CMParts
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_STATIC_JAVA_LIBRARIES := org.cyanogenmod.platform.internal
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ android-support-v4 \
+ android-support-v13 \
+ android-support-v7-recyclerview \
+ android-support-v7-preference \
+ android-support-v7-appcompat \
+ android-support-v14-preference \
+ jsr305 \
+ org.cyanogenmod.platform.internal
+
+LOCAL_RESOURCE_DIR := \
+ $(LOCAL_PATH)/res \
+ frameworks/support/v7/preference/res \
+ frameworks/support/v14/preference/res \
+ frameworks/support/v7/appcompat/res \
+ frameworks/support/v7/recyclerview/res
+
+LOCAL_AAPT_FLAGS := --auto-add-overlay \
+ --extra-packages android.support.v7.preference:android.support.v14.preference:android.support.v17.preference:android.support.v7.appcompat:android.support.v7.recyclerview
+
LOCAL_CERTIFICATE := platform
LOCAL_PRIVILEGED_MODULE := true
LOCAL_MODULE_TAGS := optional
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+ifneq ($(INCREMENTAL_BUILDS),)
+ LOCAL_PROGUARD_ENABLED := disabled
+ LOCAL_JACK_ENABLED := incremental
+ LOCAL_DX_FLAGS := --multi-dex
+ LOCAL_JACK_FLAGS := --multi-dex native
+endif
+
include $(BUILD_PACKAGE)
diff --git a/res/layout/layout_preference_frame.xml b/res/layout/layout_preference_frame.xml
new file mode 100644
index 0000000..eec3d7a
--- /dev/null
+++ b/res/layout/layout_preference_frame.xml
@@ -0,0 +1,18 @@
+<!--
+ Copyright (C) 2015 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.
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
diff --git a/res/layout/loading_container.xml b/res/layout/loading_container.xml
new file mode 100644
index 0000000..5a165de
--- /dev/null
+++ b/res/layout/loading_container.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/loading_container"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="gone"
+ android:gravity="center">
+
+ <ProgressBar style="?android:attr/progressBarStyleLarge"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <TextView android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:text="@string/loading"
+ android:paddingTop="4dip"
+ android:singleLine="true" />
+
+</LinearLayout>
diff --git a/res/layout/preference_list_fragment.xml b/res/layout/preference_list_fragment.xml
new file mode 100644
index 0000000..2e51e47
--- /dev/null
+++ b/res/layout/preference_list_fragment.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, 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.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/container_material"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@android:color/transparent">
+
+ <FrameLayout android:id="@+id/pinned_header"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:visibility="gone" />
+
+ <FrameLayout
+ android:id="@android:id/list_container"
+ android:layout_height="0px"
+ android:layout_weight="1"
+ android:layout_width="match_parent"
+ android:paddingStart="@dimen/settings_side_margin"
+ android:paddingEnd="@dimen/settings_side_margin">
+
+ <ListView android:id="@+id/backup_list"
+ style="@style/PreferenceFragmentListSinglePane"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingTop="@dimen/dashboard_padding_top"
+ android:paddingBottom="@dimen/dashboard_padding_bottom"
+ android:scrollbarStyle="@*android:integer/preference_fragment_scrollbarStyle"
+ android:clipToPadding="false"
+ android:drawSelectorOnTop="false"
+ android:elevation="@dimen/dashboard_category_elevation"
+ android:visibility="gone"
+ android:scrollbarAlwaysDrawVerticalTrack="true" />
+
+ <include layout="@layout/loading_container" />
+
+ </FrameLayout>
+
+ <TextView android:id="@android:id/empty"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:padding="@*android:dimen/preference_fragment_padding_side"
+ android:layout_gravity="center"
+ android:gravity="center_vertical"
+ android:visibility="gone" />
+
+ <RelativeLayout android:id="@+id/button_bar"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_weight="0"
+ android:visibility="gone">
+
+ <Button android:id="@+id/back_button"
+ android:layout_width="150dip"
+ android:layout_height="wrap_content"
+ android:layout_margin="5dip"
+ android:layout_alignParentStart="true"
+ android:text="@*android:string/back_button_label"
+ />
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentEnd="true">
+
+ <Button android:id="@+id/skip_button"
+ android:layout_width="150dip"
+ android:layout_height="wrap_content"
+ android:layout_margin="5dip"
+ android:text="@*android:string/skip_button_label"
+ android:visibility="gone"
+ />
+
+ <Button android:id="@+id/next_button"
+ android:layout_width="150dip"
+ android:layout_height="wrap_content"
+ android:layout_margin="5dip"
+ android:text="@*android:string/next_button_label"
+ />
+
+ </LinearLayout>
+
+ </RelativeLayout>
+
+</LinearLayout>
+
diff --git a/res/layout/preference_material_settings.xml b/res/layout/preference_material_settings.xml
new file mode 100644
index 0000000..b8a00f2
--- /dev/null
+++ b/res/layout/preference_material_settings.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+
+<!-- Based off frameworks/base/core/res/res/layout/preference_material.xml
+ except that this has the negative margin on the image removed. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeightSmall"
+ android:gravity="center_vertical"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:background="?android:attr/activatedBackgroundIndicator"
+ android:clipToPadding="false">
+
+ <LinearLayout
+ android:id="@id/icon_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:minWidth="60dp"
+ android:gravity="start|center_vertical"
+ android:orientation="horizontal"
+ android:paddingEnd="12dp"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp">
+ <com.android.internal.widget.PreferenceImageView
+ android:id="@android:id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxWidth="48dp"
+ android:maxHeight="48dp" />
+ </LinearLayout>
+
+ <RelativeLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:paddingTop="16dp"
+ android:paddingBottom="16dp">
+
+ <TextView android:id="@android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:ellipsize="marquee" />
+
+ <TextView android:id="@android:id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@android:id/title"
+ android:layout_alignStart="@android:id/title"
+ android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+ android:textColor="?android:attr/textColorSecondary"
+ android:maxLines="10" />
+
+ </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="end|center_vertical"
+ android:paddingStart="16dp"
+ android:orientation="vertical" />
+
+</LinearLayout>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index a14d36b..a10b307 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -15,9 +15,22 @@
-->
<resources>
+
<!-- ActionBar height -->
<dimen name="actionbar_size">56dip</dimen>
+ <!-- ActionBar contentInsetStart -->
+ <dimen name="actionbar_contentInsetStart">16dp</dimen>
+
+ <!-- Dashboard padding in its container -->
+ <dimen name="dashboard_padding_start">0dp</dimen>
+ <dimen name="dashboard_padding_end">0dp</dimen>
+ <dimen name="dashboard_padding_top">0dp</dimen>
+ <dimen name="dashboard_padding_bottom">0dp</dimen>
+
+ <!-- Dashboard category panel elevation -->
+ <dimen name="dashboard_category_elevation">2dp</dimen>
+
<dimen name="settings_side_margin">0dip</dimen>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 7835732..f810add 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -15,6 +15,18 @@
-->
<resources>
+ <style name="Preference">
+ <item name="android:layout">@layout/preference_material_settings</item>
+ </style>
+
+ <style name="EditTextPreference" parent="@*android:style/Preference.Material.DialogPreference.EditTextPreference">
+ <item name="android:dialogLayout">@layout/preference_dialog_edittext</item>
+ </style>
+
+ <style name="PreferenceFragmentStyle" parent="@*android:style/PreferenceFragment.Material">
+ <item name="android:layout">@layout/preference_list_fragment</item>
+ </style>
+
<style name="PreferenceHeaderPanelSinglePane">
<item name="android:layout_marginStart">0dp</item>
<item name="android:layout_marginEnd">0dp</item>
@@ -50,5 +62,21 @@
<item name="android:scrollbarStyle">outsideOverlay</item>
</style>
-
+ <style name="SettingsPreferenceHeaderPanel" parent="@*android:style/PreferenceHeaderPanel">
+ </style>
+
+ <style name="SettingsPreferenceHeaderList" parent="@*android:style/PreferenceHeaderList">
+ </style>
+
+ <style name="TextAppearance.Medium" parent="@android:style/TextAppearance.Material.Medium" />
+ <style name="TextAppearance.Small" parent="@android:style/TextAppearance.Material.Small" />
+ <style name="TextAppearance.Switch" parent="@android:style/TextAppearance.Material.Title" />
+
+ <style name="TextAppearance.CategoryTitle" parent="@android:style/TextAppearance.Material.Body2">
+ <item name="android:textColor">?android:attr/textColorSecondary</item>
+ </style>
+
+ <style name="TextAppearance.TileTitle" parent="@android:style/TextAppearance.Material.Subhead" />
+ <style name="TextAppearance.TileSubTitle" parent="@android:style/TextAppearance.Material.Body1" />
+
</resources>
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 8c10990..e575ba4 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -15,9 +15,33 @@
-->
<resources>
+ <style name="Theme.ActionBar" parent="@android:style/Widget.Material.ActionBar.Solid">
+ <item name="android:contentInsetStart">@dimen/actionbar_contentInsetStart</item>
+ </style>
+
+ <style name="ThemeOverlay.AlertDialog" parent="@android:style/ThemeOverlay.Material.Dialog.Alert">
+ <item name="android:windowSoftInputMode">adjustResize</item>
+ </style>
+
+ <style name="Theme.AlertDialog" parent="@*android:style/Theme.Material.Settings.Dialog.Alert">
+ <item name="android:windowSoftInputMode">adjustResize</item>
+
+ <!-- Redefine the ActionBar style for contentInsetStart -->
+ <item name="android:actionBarStyle">@style/Theme.ActionBar</item>
+ </style>
+
+ <style name="PreferenceTheme" parent="@android:style/Theme.DeviceDefault.Settings">
+ <item name="@android:preferenceStyle">@style/Preference</item>
+ <item name="@android:editTextPreferenceStyle">@style/EditTextPreference</item>
+ <item name="@dropdownPreferenceStyle">@style/Preference.DropDown.Material</item>
+ <item name="@android:preferenceFragmentStyle">@style/PreferenceFragmentStyle</item>
+ </style>
+
<style name="Theme.SettingsBase" parent="@android:style/Theme.Material.Settings" />
+
<style name="Theme.Settings" parent="Theme.SettingsBase">
+ <item name="preferenceTheme">@style/PreferenceTheme</item>
<item name="@*android:preferenceHeaderPanelStyle">@style/PreferenceHeaderPanelSinglePane</item>
<item name="@*android:preferencePanelStyle">@style/PreferencePanelSinglePane</item>
<item name="@*android:preferenceListStyle">@style/PreferenceHeaderListSinglePane</item>
@@ -25,9 +49,21 @@
<item name="@*android:preferenceFragmentPaddingSide">@dimen/settings_side_margin</item>
<!-- Redefine the ActionBar style for contentInsetStart -->
+ <item name="android:actionBarStyle">@style/Theme.ActionBar</item>
<item name="@*android:actionBarSize">@dimen/actionbar_size</item>
<item name="preferenceBackgroundColor">@drawable/preference_background</item>
- </style>
+
+ <!-- For all Alert Dialogs -->
+ <item name="android:alertDialogTheme">@style/Theme.AlertDialog</item>
+ </style>
+
+ <style name="Theme.DialogWhenLarge" parent="@*android:style/Theme.Material.Settings.DialogWhenLarge">
+ <!-- Redefine the ActionBar style for contentInsetStart -->
+ <item name="android:actionBarStyle">@style/Theme.ActionBar</item>
+
+ <item name="preferenceBackgroundColor">@drawable/preference_background</item>
+ </style>
+
</resources>
diff --git a/src/org/cyanogenmod/cmparts/CMGlobalSettingSwitchPreference.java b/src/org/cyanogenmod/cmparts/CMGlobalSettingSwitchPreference.java
index 7b2d2d9..4190bf8 100644
--- a/src/org/cyanogenmod/cmparts/CMGlobalSettingSwitchPreference.java
+++ b/src/org/cyanogenmod/cmparts/CMGlobalSettingSwitchPreference.java
@@ -17,7 +17,7 @@
package org.cyanogenmod.cmparts;
import android.content.Context;
-import android.preference.SwitchPreference;
+import android.support.v14.preference.SwitchPreference;
import android.util.AttributeSet;
import cyanogenmod.providers.CMSettings;
@@ -56,10 +56,4 @@
return CMSettings.Global.getInt(getContext().getContentResolver(),
getKey(), defaultReturnValue ? 1 : 0) != 0;
}
-
- protected boolean isPersisted() {
- // Using getString instead of getInt so we can simply check for null
- // instead of catching an exception. (All values are stored as strings.)
- return CMSettings.Global.getString(getContext().getContentResolver(), getKey()) != null;
- }
}
diff --git a/src/org/cyanogenmod/cmparts/CMSecureSettingSwitchPreference.java b/src/org/cyanogenmod/cmparts/CMSecureSettingSwitchPreference.java
index 1f0d72a..2226e79 100644
--- a/src/org/cyanogenmod/cmparts/CMSecureSettingSwitchPreference.java
+++ b/src/org/cyanogenmod/cmparts/CMSecureSettingSwitchPreference.java
@@ -17,7 +17,7 @@
package org.cyanogenmod.cmparts;
import android.content.Context;
-import android.preference.SwitchPreference;
+import android.support.v14.preference.SwitchPreference;
import android.util.AttributeSet;
import cyanogenmod.providers.CMSettings;
diff --git a/src/org/cyanogenmod/cmparts/CMSystemSettingSwitchPreference.java b/src/org/cyanogenmod/cmparts/CMSystemSettingSwitchPreference.java
index 92c3622..fa0acce 100644
--- a/src/org/cyanogenmod/cmparts/CMSystemSettingSwitchPreference.java
+++ b/src/org/cyanogenmod/cmparts/CMSystemSettingSwitchPreference.java
@@ -17,7 +17,7 @@
package org.cyanogenmod.cmparts;
import android.content.Context;
-import android.preference.SwitchPreference;
+import android.support.v14.preference.SwitchPreference;
import android.util.AttributeSet;
import cyanogenmod.providers.CMSettings;
@@ -56,10 +56,4 @@
return CMSettings.System.getInt(getContext().getContentResolver(),
getKey(), defaultReturnValue ? 1 : 0) != 0;
}
-
- protected boolean isPersisted() {
- // Using getString instead of getInt so we can simply check for null
- // instead of catching an exception. (All values are stored as strings.)
- return CMSettings.System.getString(getContext().getContentResolver(), getKey()) != null;
- }
}
diff --git a/src/org/cyanogenmod/cmparts/CustomDialogPreference.java b/src/org/cyanogenmod/cmparts/CustomDialogPreference.java
new file mode 100644
index 0000000..fc25b1f
--- /dev/null
+++ b/src/org/cyanogenmod/cmparts/CustomDialogPreference.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+package org.cyanogenmod.cmparts;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v14.preference.PreferenceDialogFragment;
+import android.support.v7.preference.DialogPreference;
+import android.util.AttributeSet;
+import android.view.View;
+
+public class CustomDialogPreference extends DialogPreference {
+
+ private CustomPreferenceDialogFragment mFragment;
+
+ public CustomDialogPreference(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ public CustomDialogPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public CustomDialogPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public CustomDialogPreference(Context context) {
+ super(context);
+ }
+
+ public boolean isDialogOpen() {
+ return getDialog() != null && getDialog().isShowing();
+ }
+
+ public Dialog getDialog() {
+ return mFragment != null ? mFragment.getDialog() : null;
+ }
+
+ protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
+ DialogInterface.OnClickListener listener) {
+ }
+
+ protected void onDialogClosed(boolean positiveResult) {
+ }
+
+ protected void onClick(DialogInterface dialog, int which) {
+ }
+
+ protected void onBindDialogView(View view) {
+ }
+
+ private void setFragment(CustomPreferenceDialogFragment fragment) {
+ mFragment = fragment;
+ }
+
+ public static class CustomPreferenceDialogFragment extends PreferenceDialogFragment {
+
+ public static CustomPreferenceDialogFragment newInstance(String key) {
+ final CustomPreferenceDialogFragment fragment = new CustomPreferenceDialogFragment();
+ final Bundle b = new Bundle(1);
+ b.putString(ARG_KEY, key);
+ fragment.setArguments(b);
+ return fragment;
+ }
+
+ private CustomDialogPreference getCustomizablePreference() {
+ return (CustomDialogPreference) getPreference();
+ }
+
+ @Override
+ protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
+ super.onPrepareDialogBuilder(builder);
+ getCustomizablePreference().setFragment(this);
+ getCustomizablePreference().onPrepareDialogBuilder(builder, this);
+ }
+
+ @Override
+ public void onDialogClosed(boolean positiveResult) {
+ getCustomizablePreference().onDialogClosed(positiveResult);
+ }
+
+ @Override
+ protected void onBindDialogView(View view) {
+ super.onBindDialogView(view);
+ getCustomizablePreference().onBindDialogView(view);
+ }
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ super.onClick(dialog, which);
+ getCustomizablePreference().onClick(dialog, which);
+ }
+ }
+}
diff --git a/src/org/cyanogenmod/cmparts/LayoutPreference.java b/src/org/cyanogenmod/cmparts/LayoutPreference.java
new file mode 100644
index 0000000..5e9786b
--- /dev/null
+++ b/src/org/cyanogenmod/cmparts/LayoutPreference.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+package org.cyanogenmod.cmparts;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+public class LayoutPreference extends Preference {
+
+ private View mRootView;
+
+ public LayoutPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ final TypedArray a = context.obtainStyledAttributes(
+ attrs, com.android.internal.R.styleable.Preference, 0, 0);
+ int layoutResource = a.getResourceId(com.android.internal.R.styleable.Preference_layout,
+ 0);
+ if (layoutResource == 0) {
+ throw new IllegalArgumentException("LayoutPreference requires a layout to be defined");
+ }
+ // Need to create view now so that findViewById can be called immediately.
+ final View view = LayoutInflater.from(getContext())
+ .inflate(layoutResource, null, false);
+ setView(view);
+ }
+
+ public LayoutPreference(Context context, int resource) {
+ this(context, LayoutInflater.from(context).inflate(resource, null, false));
+ }
+
+ public LayoutPreference(Context context, View view) {
+ super(context);
+ setView(view);
+ }
+
+ private void forceCustomPadding(View view, boolean additive) {
+ final Resources res = view.getResources();
+ final int paddingSide = res.getDimensionPixelSize(R.dimen.settings_side_margin);
+
+ final int paddingStart = paddingSide + (additive ? view.getPaddingStart() : 0);
+ final int paddingEnd = paddingSide + (additive ? view.getPaddingEnd() : 0);
+ final int paddingBottom = res.getDimensionPixelSize(
+ com.android.internal.R.dimen.preference_fragment_padding_bottom);
+
+ view.setPaddingRelative(paddingStart, 0, paddingEnd, paddingBottom);
+ }
+
+ private void setView(View view) {
+ setLayoutResource(R.layout.layout_preference_frame);
+ setSelectable(false);
+ //final ViewGroup allDetails = (ViewGroup) view.findViewById(R.id.all_details);
+ //if (allDetails != null) {
+ // forceCustomPadding(allDetails, true /* additive padding */);
+ //}
+ mRootView = view;
+ setShouldDisableView(false);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder view) {
+ FrameLayout layout = (FrameLayout) view.itemView;
+ layout.removeAllViews();
+ ViewGroup parent = (ViewGroup) mRootView.getParent();
+ if (parent != null) {
+ parent.removeView(mRootView);
+ }
+ layout.addView(mRootView);
+ }
+
+ public View findViewById(int id) {
+ return mRootView.findViewById(id);
+ }
+
+}
diff --git a/src/org/cyanogenmod/cmparts/SelfAvailablePreference.java b/src/org/cyanogenmod/cmparts/SelfAvailablePreference.java
new file mode 100644
index 0000000..58afc90
--- /dev/null
+++ b/src/org/cyanogenmod/cmparts/SelfAvailablePreference.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+package org.cyanogenmod.cmparts;
+
+import android.content.Context;
+
+/**
+ * Interface for classes whose instances can provide the availability of the preference.
+ */
+public interface SelfAvailablePreference {
+ /**
+ * @return the availability of the preference. Please make sure the availability in managed
+ * profile is taken into account.
+ */
+ boolean isAvailable(Context context);
+}
diff --git a/src/org/cyanogenmod/cmparts/SettingsPreferenceFragment.java b/src/org/cyanogenmod/cmparts/SettingsPreferenceFragment.java
index 73811e3..f2825e5 100644
--- a/src/org/cyanogenmod/cmparts/SettingsPreferenceFragment.java
+++ b/src/org/cyanogenmod/cmparts/SettingsPreferenceFragment.java
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2016 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,24 +16,437 @@
package org.cyanogenmod.cmparts;
+import android.app.Activity;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.Fragment;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.PackageManager;
import android.os.Bundle;
-import android.preference.Preference;
-import android.preference.PreferenceFragment;
+import android.support.annotation.XmlRes;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceGroup;
+import android.support.v7.preference.PreferenceGroupAdapter;
+import android.support.v7.preference.PreferenceScreen;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.text.TextUtils;
+import android.util.ArrayMap;
import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.view.animation.*;
+import java.util.UUID;
+
+/**
+ * Base class for Settings fragments, with some helper functions and dialog management.
+ */
public abstract class SettingsPreferenceFragment extends PreferenceFragment
implements DialogCreatable {
- private static final String TAG = "SettingsPreferenceFragment";
+ /**
+ * The Help Uri Resource key. This can be passed as an extra argument when creating the
+ * Fragment.
+ **/
+ public static final String HELP_URI_RESOURCE_KEY = "help_uri_resource";
+
+ private static final String TAG = "SettingsPreference";
+
+ private static final int DELAY_HIGHLIGHT_DURATION_MILLIS = 600;
+
+ private static final String SAVE_HIGHLIGHTED_KEY = "android:preference_highlighted";
private SettingsDialogFragment mDialogFragment;
+ private String mHelpUri;
+
+ private static final int ORDER_FIRST = -1;
+ private static final int ORDER_LAST = Integer.MAX_VALUE -1;
+
+ // Cache the content resolver for async callbacks
+ private ContentResolver mContentResolver;
+
+ private String mPreferenceKey;
+ private boolean mPreferenceHighlighted = false;
+
+ private RecyclerView.Adapter mCurrentRootAdapter;
+ private boolean mIsDataSetObserverRegistered = false;
+ private RecyclerView.AdapterDataObserver mDataSetObserver =
+ new RecyclerView.AdapterDataObserver() {
+ @Override
+ public void onChanged() {
+ onDataSetChanged();
+ }
+ };
+
+ private ViewGroup mPinnedHeaderFrameLayout;
+ private ViewGroup mButtonBar;
+
+ private LayoutPreference mHeader;
+
+ private LayoutPreference mFooter;
+ private View mEmptyView;
+ private LinearLayoutManager mLayoutManager;
+ private HighlightablePreferenceGroupAdapter mAdapter;
+ private ArrayMap<String, Preference> mPreferenceCache;
+ private boolean mAnimationAllowed;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ if (icicle != null) {
+ mPreferenceHighlighted = icicle.getBoolean(SAVE_HIGHLIGHTED_KEY);
+ }
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ final View root = super.onCreateView(inflater, container, savedInstanceState);
+ mPinnedHeaderFrameLayout = (ViewGroup) root.findViewById(R.id.pinned_header);
+ mButtonBar = (ViewGroup) root.findViewById(R.id.button_bar);
+ return root;
+ }
+
+ @Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+ }
+
+ @Override
+ public void addPreferencesFromResource(@XmlRes int preferencesResId) {
+ super.addPreferencesFromResource(preferencesResId);
+ checkAvailablePrefs(getPreferenceScreen());
+ }
+
+ private void checkAvailablePrefs(PreferenceGroup preferenceGroup) {
+ if (preferenceGroup == null) return;
+ for (int i = 0; i < preferenceGroup.getPreferenceCount(); i++) {
+ Preference pref = preferenceGroup.getPreference(i);
+ if (pref instanceof SelfAvailablePreference
+ && !((SelfAvailablePreference) pref).isAvailable(getContext())) {
+ preferenceGroup.removePreference(pref);
+ } else if (pref instanceof PreferenceGroup) {
+ checkAvailablePrefs((PreferenceGroup) pref);
+ }
+ }
+ }
+
+ public ViewGroup getButtonBar() {
+ return mButtonBar;
+ }
+
+ public View setPinnedHeaderView(int layoutResId) {
+ final LayoutInflater inflater = getActivity().getLayoutInflater();
+ final View pinnedHeader =
+ inflater.inflate(layoutResId, mPinnedHeaderFrameLayout, false);
+ setPinnedHeaderView(pinnedHeader);
+ return pinnedHeader;
+ }
+
+ public void setPinnedHeaderView(View pinnedHeader) {
+ mPinnedHeaderFrameLayout.addView(pinnedHeader);
+ mPinnedHeaderFrameLayout.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ outState.putBoolean(SAVE_HIGHLIGHTED_KEY, mPreferenceHighlighted);
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ final Bundle args = getArguments();
+ if (args != null) {
+ mPreferenceKey = args.getString(PartsActivity.EXTRA_FRAGMENT_ARG_KEY);
+ highlightPreferenceIfNeeded();
+ }
+ }
+
+ @Override
+ protected void onBindPreferences() {
+ registerObserverIfNeeded();
+ }
+
+ @Override
+ protected void onUnbindPreferences() {
+ unregisterObserverIfNeeded();
+ }
+
+ public void showLoadingWhenEmpty() {
+ View loading = getView().findViewById(R.id.loading_container);
+ setEmptyView(loading);
+ }
+
+ public void handleLoadingContainer(View loading, View doneLoading, boolean done,
+ boolean animate) {
+ setViewShown(loading, !done, animate);
+ setViewShown(doneLoading, done, animate);
+ }
+
+ private void setViewShown(final View view, boolean shown, boolean animate) {
+ if (animate) {
+ Animation animation = AnimationUtils.loadAnimation(view.getContext(),
+ shown ? android.R.anim.fade_in : android.R.anim.fade_out);
+ if (shown) {
+ view.setVisibility(View.VISIBLE);
+ } else {
+ animation.setAnimationListener(new Animation.AnimationListener() {
+ @Override
+ public void onAnimationStart(Animation animation) {
+ }
+
+ @Override
+ public void onAnimationRepeat(Animation animation) {
+ }
+
+ @Override
+ public void onAnimationEnd(Animation animation) {
+ view.setVisibility(View.INVISIBLE);
+ }
+ });
+ }
+ view.startAnimation(animation);
+ } else {
+ view.clearAnimation();
+ view.setVisibility(shown ? View.VISIBLE : View.INVISIBLE);
+ }
+ }
+
+ public void setLoading(boolean loading, boolean animate) {
+ View loading_container = getView().findViewById(R.id.loading_container);
+ handleLoadingContainer(loading_container, getListView(), !loading, animate);
+ }
+
+ public void registerObserverIfNeeded() {
+ if (!mIsDataSetObserverRegistered) {
+ if (mCurrentRootAdapter != null) {
+ mCurrentRootAdapter.unregisterAdapterDataObserver(mDataSetObserver);
+ }
+ mCurrentRootAdapter = getListView().getAdapter();
+ mCurrentRootAdapter.registerAdapterDataObserver(mDataSetObserver);
+ mIsDataSetObserverRegistered = true;
+ onDataSetChanged();
+ }
+ }
+
+ public void unregisterObserverIfNeeded() {
+ if (mIsDataSetObserverRegistered) {
+ if (mCurrentRootAdapter != null) {
+ mCurrentRootAdapter.unregisterAdapterDataObserver(mDataSetObserver);
+ mCurrentRootAdapter = null;
+ }
+ mIsDataSetObserverRegistered = false;
+ }
+ }
+
+ public void highlightPreferenceIfNeeded() {
+ if (isAdded() && !mPreferenceHighlighted &&!TextUtils.isEmpty(mPreferenceKey)) {
+ highlightPreference(mPreferenceKey);
+ }
+ }
+
+ protected void onDataSetChanged() {
+ highlightPreferenceIfNeeded();
+ updateEmptyView();
+ }
+
+ public LayoutPreference getHeaderView() {
+ return mHeader;
+ }
+
+ public LayoutPreference getFooterView() {
+ return mFooter;
+ }
+
+ protected void setHeaderView(int resource) {
+ mHeader = new LayoutPreference(getPrefContext(), resource);
+ addPreferenceToTop(mHeader);
+ }
+
+ protected void setHeaderView(View view) {
+ mHeader = new LayoutPreference(getPrefContext(), view);
+ addPreferenceToTop(mHeader);
+ }
+
+ private void addPreferenceToTop(LayoutPreference preference) {
+ preference.setOrder(ORDER_FIRST);
+ if (getPreferenceScreen() != null) {
+ getPreferenceScreen().addPreference(preference);
+ }
+ }
+
+ protected void setFooterView(int resource) {
+ setFooterView(resource != 0 ? new LayoutPreference(getPrefContext(), resource) : null);
+ }
+
+ protected void setFooterView(View v) {
+ setFooterView(v != null ? new LayoutPreference(getPrefContext(), v) : null);
+ }
+
+ private void setFooterView(LayoutPreference footer) {
+ if (getPreferenceScreen() != null && mFooter != null) {
+ getPreferenceScreen().removePreference(mFooter);
+ }
+ if (footer != null) {
+ mFooter = footer;
+ mFooter.setOrder(ORDER_LAST);
+ if (getPreferenceScreen() != null) {
+ getPreferenceScreen().addPreference(mFooter);
+ }
+ } else {
+ mFooter = null;
+ }
+ }
+
+ @Override
+ public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
+ if (preferenceScreen != null && !preferenceScreen.isAttached()) {
+ // Without ids generated, the RecyclerView won't animate changes to the preferences.
+ preferenceScreen.setShouldUseGeneratedIds(mAnimationAllowed);
+ }
+ super.setPreferenceScreen(preferenceScreen);
+ if (preferenceScreen != null) {
+ if (mHeader != null) {
+ preferenceScreen.addPreference(mHeader);
+ }
+ if (mFooter != null) {
+ preferenceScreen.addPreference(mFooter);
+ }
+ }
+ }
+
+ private void updateEmptyView() {
+ if (mEmptyView == null) return;
+ if (getPreferenceScreen() != null) {
+ boolean show = (getPreferenceScreen().getPreferenceCount()
+ - (mHeader != null ? 1 : 0)
+ - (mFooter != null ? 1 : 0)) <= 0;
+ mEmptyView.setVisibility(show ? View.VISIBLE : View.GONE);
+ } else {
+ mEmptyView.setVisibility(View.VISIBLE);
+ }
+ }
+
+ public void setEmptyView(View v) {
+ if (mEmptyView != null) {
+ mEmptyView.setVisibility(View.GONE);
+ }
+ mEmptyView = v;
+ updateEmptyView();
+ }
+
+ public View getEmptyView() {
+ return mEmptyView;
+ }
+
+ /**
+ * Return a valid ListView position or -1 if none is found
+ */
+ private int canUseListViewForHighLighting(String key) {
+ if (getListView() == null) {
+ return -1;
+ }
+
+ RecyclerView listView = getListView();
+ RecyclerView.Adapter adapter = listView.getAdapter();
+
+ if (adapter != null && adapter instanceof PreferenceGroupAdapter) {
+ return findListPositionFromKey((PreferenceGroupAdapter) adapter, key);
+ }
+
+ return -1;
+ }
+
+ @Override
+ public RecyclerView.LayoutManager onCreateLayoutManager() {
+ mLayoutManager = new LinearLayoutManager(getContext());
+ return mLayoutManager;
+ }
+
+ @Override
+ protected RecyclerView.Adapter onCreateAdapter(PreferenceScreen preferenceScreen) {
+ mAdapter = new HighlightablePreferenceGroupAdapter(preferenceScreen);
+ return mAdapter;
+ }
+
+ protected void setAnimationAllowed(boolean animationAllowed) {
+ mAnimationAllowed = animationAllowed;
+ }
+
+ protected void cacheRemoveAllPrefs(PreferenceGroup group) {
+ mPreferenceCache = new ArrayMap<String, Preference>();
+ final int N = group.getPreferenceCount();
+ for (int i = 0; i < N; i++) {
+ Preference p = group.getPreference(i);
+ if (TextUtils.isEmpty(p.getKey())) {
+ continue;
+ }
+ mPreferenceCache.put(p.getKey(), p);
+ }
+ }
+
+ protected Preference getCachedPreference(String key) {
+ return mPreferenceCache != null ? mPreferenceCache.remove(key) : null;
+ }
+
+ protected void removeCachedPrefs(PreferenceGroup group) {
+ for (Preference p : mPreferenceCache.values()) {
+ group.removePreference(p);
+ }
+ }
+
+ protected int getCachedCount() {
+ return mPreferenceCache.size();
+ }
+
+ private void highlightPreference(String key) {
+ final int position = canUseListViewForHighLighting(key);
+ if (position >= 0) {
+ mPreferenceHighlighted = true;
+ mLayoutManager.scrollToPosition(position);
+
+ getView().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mAdapter.highlight(position);
+ }
+ }, DELAY_HIGHLIGHT_DURATION_MILLIS);
+ }
+ }
+
+ private int findListPositionFromKey(PreferenceGroupAdapter adapter, String key) {
+ final int count = adapter.getItemCount();
+ for (int n = 0; n < count; n++) {
+ final Preference preference = adapter.getItem(n);
+ final String preferenceKey = preference.getKey();
+ if (preferenceKey != null && preferenceKey.equals(key)) {
+ return n;
+ }
+ }
+ return -1;
+ }
+
protected void removePreference(String key) {
Preference pref = findPreference(key);
if (pref != null) {
@@ -42,6 +454,52 @@
}
}
+ /*
+ * The name is intentionally made different from Activity#finish(), so that
+ * users won't misunderstand its meaning.
+ */
+ public final void finishFragment() {
+ getActivity().onBackPressed();
+ }
+
+ // Some helpers for functions used by the settings fragments when they were activities
+
+ /**
+ * Returns the ContentResolver from the owning Activity.
+ */
+ protected ContentResolver getContentResolver() {
+ Context context = getActivity();
+ if (context != null) {
+ mContentResolver = context.getContentResolver();
+ }
+ return mContentResolver;
+ }
+
+ /**
+ * Returns the specified system service from the owning Activity.
+ */
+ protected Object getSystemService(final String name) {
+ return getActivity().getSystemService(name);
+ }
+
+ /**
+ * Returns the PackageManager from the owning Activity.
+ */
+ protected PackageManager getPackageManager() {
+ return getActivity().getPackageManager();
+ }
+
+ @Override
+ public void onDetach() {
+ if (isRemoving()) {
+ if (mDialogFragment != null) {
+ mDialogFragment.dismiss();
+ mDialogFragment = null;
+ }
+ }
+ super.onDetach();
+ }
+
// Dialog management
protected void showDialog(int dialogId) {
@@ -66,6 +524,18 @@
mDialogFragment = null;
}
+ protected void removeDialog(int dialogId, boolean stateLossAllowed) {
+ if (stateLossAllowed) {
+ if (mDialogFragment != null && mDialogFragment.getDialogId() == dialogId) {
+ getFragmentManager().beginTransaction().remove(mDialogFragment).
+ commitAllowingStateLoss();
+ }
+ mDialogFragment = null;
+ } else {
+ removeDialog(dialogId);
+ }
+ }
+
/**
* Sets the OnCancelListener of the dialog shown. This method can only be
* called after showDialog(int) and before removeDialog(int). The method
@@ -92,6 +562,25 @@
// override in subclass to attach a dismiss listener, for instance
}
+ @Override
+ public void onDisplayPreferenceDialog(Preference preference) {
+ if (preference.getKey() == null) {
+ // Auto-key preferences that don't have a key, so the dialog can find them.
+ preference.setKey(UUID.randomUUID().toString());
+ }
+ DialogFragment f = null;
+ if (preference instanceof CustomDialogPreference) {
+ f = CustomDialogPreference.CustomPreferenceDialogFragment
+ .newInstance(preference.getKey());
+ } else {
+ super.onDisplayPreferenceDialog(preference);
+ return;
+ }
+ f.setTargetFragment(this, 0);
+ f.show(getFragmentManager(), "dialog_preference");
+ onDialogShowing();
+ }
+
public static class SettingsDialogFragment extends DialogFragment {
private static final String KEY_DIALOG_ID = "key_dialog_id";
private static final String KEY_PARENT_FRAGMENT_ID = "key_parent_fragment_id";
@@ -193,5 +682,69 @@
}
}
}
-}
+ public void finish() {
+ Activity activity = getActivity();
+ if (activity == null) return;
+ if (getFragmentManager().getBackStackEntryCount() > 0) {
+ getFragmentManager().popBackStack();
+ } else {
+ activity.finish();
+ }
+ }
+
+ protected Intent getIntent() {
+ if (getActivity() == null) {
+ return null;
+ }
+ return getActivity().getIntent();
+ }
+
+ protected void setResult(int result, Intent intent) {
+ if (getActivity() == null) {
+ return;
+ }
+ getActivity().setResult(result, intent);
+ }
+
+ protected void setResult(int result) {
+ if (getActivity() == null) {
+ return;
+ }
+ getActivity().setResult(result);
+ }
+
+ protected final Context getPrefContext() {
+ return getPreferenceManager().getContext();
+ }
+
+ public static class HighlightablePreferenceGroupAdapter extends PreferenceGroupAdapter {
+
+ private int mHighlightPosition = -1;
+
+ public HighlightablePreferenceGroupAdapter(PreferenceGroup preferenceGroup) {
+ super(preferenceGroup);
+ }
+
+ public void highlight(int position) {
+ mHighlightPosition = position;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder, int position) {
+ super.onBindViewHolder(holder, position);
+ if (position == mHighlightPosition) {
+ View v = holder.itemView;
+ if (v.getBackground() != null) {
+ final int centerX = v.getWidth() / 2;
+ final int centerY = v.getHeight() / 2;
+ v.getBackground().setHotspot(centerX, centerY);
+ }
+ v.setPressed(true);
+ v.setPressed(false);
+ mHighlightPosition = -1;
+ }
+ }
+ }
+}
diff --git a/src/org/cyanogenmod/cmparts/SystemSettingSwitchPreference.java b/src/org/cyanogenmod/cmparts/SystemSettingSwitchPreference.java
index 2aefd69..f2111df 100644
--- a/src/org/cyanogenmod/cmparts/SystemSettingSwitchPreference.java
+++ b/src/org/cyanogenmod/cmparts/SystemSettingSwitchPreference.java
@@ -18,7 +18,7 @@
import android.content.Context;
import android.provider.Settings;
-import android.preference.SwitchPreference;
+import android.support.v14.preference.SwitchPreference;
import android.util.AttributeSet;
public class SystemSettingSwitchPreference extends SwitchPreference {
diff --git a/src/org/cyanogenmod/cmparts/privacyguard/PrivacyGuardManager.java b/src/org/cyanogenmod/cmparts/privacyguard/PrivacyGuardManager.java
index 1e8b2f3..1031eef 100644
--- a/src/org/cyanogenmod/cmparts/privacyguard/PrivacyGuardManager.java
+++ b/src/org/cyanogenmod/cmparts/privacyguard/PrivacyGuardManager.java
@@ -36,7 +36,7 @@
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
-import android.preference.PreferenceManager;
+import android.support.v7.preference.PreferenceManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
diff --git a/src/org/cyanogenmod/cmparts/privacyguard/PrivacyGuardPrefs.java b/src/org/cyanogenmod/cmparts/privacyguard/PrivacyGuardPrefs.java
index fec619f..0635948 100644
--- a/src/org/cyanogenmod/cmparts/privacyguard/PrivacyGuardPrefs.java
+++ b/src/org/cyanogenmod/cmparts/privacyguard/PrivacyGuardPrefs.java
@@ -19,10 +19,10 @@
import android.os.Bundle;
import android.provider.Settings;
-import android.preference.Preference;
-import android.preference.Preference.OnPreferenceChangeListener;
-import android.preference.PreferenceFragment;
-import android.preference.SwitchPreference;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.Preference.OnPreferenceChangeListener;
+import android.support.v14.preference.PreferenceFragment;
+import android.support.v14.preference.SwitchPreference;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -49,9 +49,7 @@
}
@Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.privacy_guard_prefs);
mPrivacyGuardDefault = (SwitchPreference) findPreference(KEY_PRIVACY_GUARD_DEFAULT);
@@ -66,7 +64,7 @@
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
final View view = super.onCreateView(inflater, container, savedInstanceState);
- final ListView list = (ListView) view.findViewById(android.R.id.list);
+ final ViewGroup list = (ViewGroup) getListView().getParent();
// our container already takes care of the padding
int paddingTop = list.getPaddingTop();
int paddingBottom = list.getPaddingBottom();