diff options
| author | Adam Powell <adamp@google.com> | 2010-11-29 17:47:48 -0800 |
|---|---|---|
| committer | Gilles Debunne <debunne@google.com> | 2011-06-08 18:25:27 -0700 |
| commit | be0a4535053bbfdebd215e244b154ac810fd8edc (patch) | |
| tree | cf30dcc2d662e90e57c8ac8769f48906b14bcb95 /core/java/android/preference/TwoStatePreference.java | |
| parent | de13001f765e30bc29a3a74bfa751cc42e426a93 (diff) | |
Add SwitchPreference
Change-Id: I073e9bfba8c4e1a625c27f976f71ea56a81ba20f
Diffstat (limited to 'core/java/android/preference/TwoStatePreference.java')
| -rw-r--r-- | core/java/android/preference/TwoStatePreference.java | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/core/java/android/preference/TwoStatePreference.java b/core/java/android/preference/TwoStatePreference.java new file mode 100644 index 000000000000..8e21c4c493a5 --- /dev/null +++ b/core/java/android/preference/TwoStatePreference.java @@ -0,0 +1,309 @@ +/* + * Copyright (C) 2010 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 android.preference; + +import android.app.Service; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.TypedArray; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.AttributeSet; +import android.view.View; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityManager; +import android.widget.TextView; + +/** + * Common base class for preferences that have two selectable states, persist a + * boolean value in SharedPreferences, and may have dependent preferences that are + * enabled/disabled based on the current state. + */ +public abstract class TwoStatePreference extends Preference { + + private CharSequence mSummaryOn; + private CharSequence mSummaryOff; + boolean mChecked; + private boolean mSendAccessibilityEventViewClickedType; + private AccessibilityManager mAccessibilityManager; + private boolean mDisableDependentsState; + + public TwoStatePreference(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + mAccessibilityManager = + (AccessibilityManager) getContext().getSystemService(Service.ACCESSIBILITY_SERVICE); + } + + public TwoStatePreference(Context context, AttributeSet attrs) { + super(context, attrs); + + mAccessibilityManager = + (AccessibilityManager) getContext().getSystemService(Service.ACCESSIBILITY_SERVICE); + } + + public TwoStatePreference(Context context) { + super(context); + + mAccessibilityManager = + (AccessibilityManager) getContext().getSystemService(Service.ACCESSIBILITY_SERVICE); + } + + @Override + protected void onClick() { + super.onClick(); + + boolean newValue = !isChecked(); + + // in onBindView() an AccessibilityEventViewClickedType is sent to announce the change + // not sending + mSendAccessibilityEventViewClickedType = true; + + if (!callChangeListener(newValue)) { + return; + } + + setChecked(newValue); + } + + /** + * Sets the checked state and saves it to the {@link SharedPreferences}. + * + * @param checked The checked state. + */ + public void setChecked(boolean checked) { + if (mChecked != checked) { + mChecked = checked; + persistBoolean(checked); + notifyDependencyChange(shouldDisableDependents()); + notifyChanged(); + } + } + + /** + * Returns the checked state. + * + * @return The checked state. + */ + public boolean isChecked() { + return mChecked; + } + + @Override + public boolean shouldDisableDependents() { + boolean shouldDisable = mDisableDependentsState ? mChecked : !mChecked; + return shouldDisable || super.shouldDisableDependents(); + } + + /** + * Sets the summary to be shown when checked. + * + * @param summary The summary to be shown when checked. + */ + public void setSummaryOn(CharSequence summary) { + mSummaryOn = summary; + if (isChecked()) { + notifyChanged(); + } + } + + /** + * @see #setSummaryOn(CharSequence) + * @param summaryResId The summary as a resource. + */ + public void setSummaryOn(int summaryResId) { + setSummaryOn(getContext().getString(summaryResId)); + } + + /** + * Returns the summary to be shown when checked. + * @return The summary. + */ + public CharSequence getSummaryOn() { + return mSummaryOn; + } + + /** + * Sets the summary to be shown when unchecked. + * + * @param summary The summary to be shown when unchecked. + */ + public void setSummaryOff(CharSequence summary) { + mSummaryOff = summary; + if (!isChecked()) { + notifyChanged(); + } + } + + /** + * @see #setSummaryOff(CharSequence) + * @param summaryResId The summary as a resource. + */ + public void setSummaryOff(int summaryResId) { + setSummaryOff(getContext().getString(summaryResId)); + } + + /** + * Returns the summary to be shown when unchecked. + * @return The summary. + */ + public CharSequence getSummaryOff() { + return mSummaryOff; + } + + /** + * Returns whether dependents are disabled when this preference is on ({@code true}) + * or when this preference is off ({@code false}). + * + * @return Whether dependents are disabled when this preference is on ({@code true}) + * or when this preference is off ({@code false}). + */ + public boolean getDisableDependentsState() { + return mDisableDependentsState; + } + + /** + * Sets whether dependents are disabled when this preference is on ({@code true}) + * or when this preference is off ({@code false}). + * + * @param disableDependentsState The preference state that should disable dependents. + */ + public void setDisableDependentsState(boolean disableDependentsState) { + mDisableDependentsState = disableDependentsState; + } + + @Override + protected Object onGetDefaultValue(TypedArray a, int index) { + return a.getBoolean(index, false); + } + + @Override + protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { + setChecked(restoreValue ? getPersistedBoolean(mChecked) + : (Boolean) defaultValue); + } + + /** + * Send an accessibility event for the given view if appropriate + * @param view View that should send the event + */ + void sendAccessibilityEventForView(View view) { + // send an event to announce the value change of the state. It is done here + // because clicking a preference does not immediately change the checked state + // for example when enabling the WiFi + if (mSendAccessibilityEventViewClickedType && + mAccessibilityManager.isEnabled() && + view.isEnabled()) { + mSendAccessibilityEventViewClickedType = false; + + int eventType = AccessibilityEvent.TYPE_VIEW_CLICKED; + view.sendAccessibilityEventUnchecked(AccessibilityEvent.obtain(eventType)); + } + } + + /** + * Sync a summary view contained within view's subhierarchy with the correct summary text. + * @param view View where a summary should be located + */ + void syncSummaryView(View view) { + // Sync the summary view + TextView summaryView = (TextView) view.findViewById(com.android.internal.R.id.summary); + if (summaryView != null) { + boolean useDefaultSummary = true; + if (mChecked && mSummaryOn != null) { + summaryView.setText(mSummaryOn); + useDefaultSummary = false; + } else if (!mChecked && mSummaryOff != null) { + summaryView.setText(mSummaryOff); + useDefaultSummary = false; + } + + if (useDefaultSummary) { + final CharSequence summary = getSummary(); + if (summary != null) { + summaryView.setText(summary); + useDefaultSummary = false; + } + } + + int newVisibility = View.GONE; + if (!useDefaultSummary) { + // Someone has written to it + newVisibility = View.VISIBLE; + } + if (newVisibility != summaryView.getVisibility()) { + summaryView.setVisibility(newVisibility); + } + } + } + + @Override + protected Parcelable onSaveInstanceState() { + final Parcelable superState = super.onSaveInstanceState(); + if (isPersistent()) { + // No need to save instance state since it's persistent + return superState; + } + + final SavedState myState = new SavedState(superState); + myState.checked = isChecked(); + return myState; + } + + @Override + protected void onRestoreInstanceState(Parcelable state) { + if (state == null || !state.getClass().equals(SavedState.class)) { + // Didn't save state for us in onSaveInstanceState + super.onRestoreInstanceState(state); + return; + } + + SavedState myState = (SavedState) state; + super.onRestoreInstanceState(myState.getSuperState()); + setChecked(myState.checked); + } + + static class SavedState extends BaseSavedState { + boolean checked; + + public SavedState(Parcel source) { + super(source); + checked = source.readInt() == 1; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeInt(checked ? 1 : 0); + } + + public SavedState(Parcelable superState) { + super(superState); + } + + public static final Parcelable.Creator<SavedState> CREATOR = + new Parcelable.Creator<SavedState>() { + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + } +} |
