diff options
author | Alan Viverette <alanv@google.com> | 2013-08-06 13:53:58 -0700 |
---|---|---|
committer | Alan Viverette <alanv@google.com> | 2013-08-06 13:53:58 -0700 |
commit | cc0e782871eb6b946ded880e391866f27953654b (patch) | |
tree | bc4440a24d436953adb8e86423a77a0b52be8f93 /src | |
parent | 279a8dfc4077ab6623213da17954e307806cddc8 (diff) | |
download | packages_apps_Settings-cc0e782871eb6b946ded880e391866f27953654b.zip packages_apps_Settings-cc0e782871eb6b946ded880e391866f27953654b.tar.gz packages_apps_Settings-cc0e782871eb6b946ded880e391866f27953654b.tar.bz2 |
Add captioning preferences screen
BUG: 9926077
Change-Id: Iea141d5d6fd0e4f134c36c51d89830b3c31abd09
Diffstat (limited to 'src')
10 files changed, 1431 insertions, 11 deletions
diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java index d2198a7..5834f99 100644 --- a/src/com/android/settings/accessibility/AccessibilitySettings.java +++ b/src/com/android/settings/accessibility/AccessibilitySettings.java @@ -95,6 +95,8 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements "select_long_press_timeout_preference"; private static final String ENABLE_ACCESSIBILITY_GESTURE_PREFERENCE_SCREEN = "enable_global_gesture_preference_screen"; + private static final String CAPTIONING_PREFERENCE_SCREEN = + "captioning_preference_screen"; private static final String DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN = "screen_magnification_preference_screen"; @@ -189,6 +191,7 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements private CheckBoxPreference mToggleSpeakPasswordPreference; private ListPreference mSelectLongPressTimeoutPreference; private Preference mNoServicesMessagePreference; + private PreferenceScreen mCaptioningPreferenceScreen; private PreferenceScreen mDisplayMagnificationPreferenceScreen; private PreferenceScreen mGlobalGesturePreferenceScreen; @@ -360,6 +363,10 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements } } + // Captioning. + mCaptioningPreferenceScreen = (PreferenceScreen) findPreference( + CAPTIONING_PREFERENCE_SCREEN); + // Display magnification. mDisplayMagnificationPreferenceScreen = (PreferenceScreen) findPreference( DISPLAY_MAGNIFICATION_PREFERENCE_SCREEN); @@ -507,6 +514,15 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements mSelectLongPressTimeoutPreference.setValue(value); mSelectLongPressTimeoutPreference.setSummary(mLongPressTimeoutValuetoTitleMap.get(value)); + // Captioning. + final boolean captioningEnabled = Settings.Secure.getInt(getContentResolver(), + Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, 0) == 1; + if (captioningEnabled) { + mCaptioningPreferenceScreen.setSummary(R.string.accessibility_feature_state_on); + } else { + mCaptioningPreferenceScreen.setSummary(R.string.accessibility_feature_state_off); + } + // Screen magnification. final boolean magnificationEnabled = Settings.Secure.getInt(getContentResolver(), Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 0) == 1; diff --git a/src/com/android/settings/accessibility/AccessibilityUtils.java b/src/com/android/settings/accessibility/AccessibilityUtils.java index fd4a34f..66a3ed2 100644 --- a/src/com/android/settings/accessibility/AccessibilityUtils.java +++ b/src/com/android/settings/accessibility/AccessibilityUtils.java @@ -1,37 +1,77 @@ +/* + * Copyright (C) 2013 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 com.android.settings.accessibility; import android.content.ComponentName; import android.content.Context; +import android.content.res.Configuration; +import android.content.res.Resources; import android.provider.Settings; -import android.provider.Settings.Secure; import android.text.TextUtils.SimpleStringSplitter; +import java.util.Collections; import java.util.HashSet; +import java.util.Locale; import java.util.Set; /** - * TODO: Insert description here. (generated by alanv) + * Utility methods used within accessibility settings. */ -public class AccessibilityUtils { - +class AccessibilityUtils { + /** + * @return the set of enabled accessibility services + */ static Set<ComponentName> getEnabledServicesFromSettings(Context context) { - String enabledServicesSetting = Settings.Secure.getString(context.getContentResolver(), - Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); + final String enabledServicesSetting = Settings.Secure.getString( + context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); if (enabledServicesSetting == null) { - enabledServicesSetting = ""; + return Collections.emptySet(); } - Set<ComponentName> enabledServices = new HashSet<ComponentName>(); - SimpleStringSplitter colonSplitter = AccessibilitySettings.sStringColonSplitter; + + final Set<ComponentName> enabledServices = new HashSet<ComponentName>(); + final SimpleStringSplitter colonSplitter = AccessibilitySettings.sStringColonSplitter; colonSplitter.setString(enabledServicesSetting); + while (colonSplitter.hasNext()) { - String componentNameString = colonSplitter.next(); - ComponentName enabledService = ComponentName.unflattenFromString( + final String componentNameString = colonSplitter.next(); + final ComponentName enabledService = ComponentName.unflattenFromString( componentNameString); if (enabledService != null) { enabledServices.add(enabledService); } } + return enabledServices; } + /** + * @return a localized version of the text resource specified by resId + */ + static CharSequence getTextForLocale(Context context, Locale locale, int resId) { + final Resources res = context.getResources(); + final Configuration config = res.getConfiguration(); + final Locale prevLocale = config.locale; + try { + config.locale = locale; + res.updateConfiguration(config, null); + return res.getText(resId); + } finally { + config.locale = prevLocale; + res.updateConfiguration(config, null); + } + } } diff --git a/src/com/android/settings/accessibility/CaptionPropertiesFragment.java b/src/com/android/settings/accessibility/CaptionPropertiesFragment.java new file mode 100644 index 0000000..1b53374 --- /dev/null +++ b/src/com/android/settings/accessibility/CaptionPropertiesFragment.java @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2013 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 com.android.settings.accessibility; + +import android.content.ContentResolver; +import android.content.res.Resources; +import android.graphics.Color; +import android.os.Bundle; +import android.preference.ListPreference; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceChangeListener; +import android.provider.Settings; +import android.view.accessibility.CaptioningManager; +import android.view.accessibility.CaptioningManager.CaptionStyle; + +import com.android.settings.R; +import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.accessibility.ListDialogPreference.OnValueChangedListener; + +/** + * Settings fragment containing captioning properties. + */ +public class CaptionPropertiesFragment extends SettingsPreferenceFragment + implements OnPreferenceChangeListener, OnValueChangedListener { + private ToggleCaptioningPreferenceFragment mParent; + + // Standard options. + private LocalePreference mLocale; + private ListPreference mFontSize; + private PresetPreference mPreset; + + // Custom options. + private ListPreference mTypeface; + private ColorPreference mForegroundColor; + private EdgeTypePreference mEdgeType; + private ColorPreference mEdgeColor; + private ColorPreference mBackgroundColor; + private ColorPreference mBackgroundOpacity; + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + addPreferencesFromResource(R.xml.captioning_settings); + initializeAllPreferences(); + updateAllPreferences(); + installUpdateListeners(); + } + + /** + * Sets the parent fragment, which is used to update the live preview. + * + * @param parent the parent fragment + */ + public void setParent(ToggleCaptioningPreferenceFragment parent) { + mParent = parent; + } + + private void initializeAllPreferences() { + final Resources res = getResources(); + final int[] presetValues = res.getIntArray(R.array.captioning_preset_selector_values); + final String[] presetTitles = res.getStringArray(R.array.captioning_preset_selector_titles); + mPreset = (PresetPreference) findPreference("captioning_preset"); + mPreset.setValues(presetValues); + mPreset.setTitles(presetTitles); + + final int[] colorValues = res.getIntArray(R.array.captioning_color_selector_values); + final String[] colorTitles = res.getStringArray(R.array.captioning_color_selector_titles); + mForegroundColor = (ColorPreference) findPreference("captioning_foreground_color"); + mForegroundColor.setTitles(colorTitles); + mForegroundColor.setValues(colorValues); + mEdgeColor = (ColorPreference) findPreference("captioning_edge_color"); + mEdgeColor.setTitles(colorTitles); + mEdgeColor.setValues(colorValues); + + final int[] bgColorValues = res.getIntArray( + R.array.captioning_background_color_selector_values); + final String[] bgColorTitles = res.getStringArray( + R.array.captioning_background_color_selector_titles); + mBackgroundColor = (ColorPreference) findPreference("captioning_background_color"); + mBackgroundColor.setTitles(bgColorTitles); + mBackgroundColor.setValues(bgColorValues); + + final int[] opacityValues = res.getIntArray(R.array.captioning_opacity_selector_values); + final String[] opacityTitles = res.getStringArray( + R.array.captioning_opacity_selector_titles); + mBackgroundOpacity = (ColorPreference) findPreference("captioning_background_opacity"); + mBackgroundOpacity.setTitles(opacityTitles); + mBackgroundOpacity.setValues(opacityValues); + + mEdgeType = (EdgeTypePreference) findPreference("captioning_edge_type"); + mTypeface = (ListPreference) findPreference("captioning_typeface"); + mFontSize = (ListPreference) findPreference("captioning_font_size"); + mLocale = (LocalePreference) findPreference("captioning_locale"); + } + + private void installUpdateListeners() { + mPreset.setOnValueChangedListener(this); + mForegroundColor.setOnValueChangedListener(this); + mEdgeColor.setOnValueChangedListener(this); + mBackgroundColor.setOnValueChangedListener(this); + mBackgroundOpacity.setOnValueChangedListener(this); + mEdgeType.setOnValueChangedListener(this); + + mTypeface.setOnPreferenceChangeListener(this); + mFontSize.setOnPreferenceChangeListener(this); + mLocale.setOnPreferenceChangeListener(this); + } + + private void updateAllPreferences() { + final ContentResolver cr = getContentResolver(); + final int preset = CaptionStyle.getRawPreset(cr); + mPreset.setValue(preset); + + final float fontSize = CaptioningManager.getFontSize(cr); + mFontSize.setValue(Float.toString(fontSize)); + + final CaptionStyle attrs = CaptionStyle.getCustomStyle(cr); + mForegroundColor.setValue(attrs.foregroundColor); + mEdgeType.setValue(attrs.edgeType); + mEdgeColor.setValue(attrs.edgeColor); + + final int backgroundColor = attrs.backgroundColor; + final int bgColor; + final int bgAlpha; + if (Color.alpha(backgroundColor) == 0) { + bgColor = Color.TRANSPARENT; + bgAlpha = (backgroundColor & 0xFF) << 24; + } else { + bgColor = backgroundColor | 0xFF000000; + bgAlpha = backgroundColor & 0xFF000000; + } + mBackgroundColor.setValue(bgColor); + mBackgroundOpacity.setValue(bgAlpha | 0xFFFFFF); + + final String rawTypeface = attrs.mRawTypeface; + mTypeface.setValue(rawTypeface == null ? "" : rawTypeface); + + final String rawLocale = CaptioningManager.getRawLocale(cr); + mLocale.setValue(rawLocale == null ? "" : rawLocale); + } + + private void refreshPreviewText() { + if (mParent != null) { + mParent.refreshPreviewText(); + } + } + + @Override + public void onValueChanged(ListDialogPreference preference, int value) { + final ContentResolver cr = getActivity().getContentResolver(); + if (mForegroundColor == preference) { + Settings.Secure.putInt( + cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR, value); + } else if (mBackgroundColor == preference || mBackgroundOpacity == preference) { + final int bgColor = mBackgroundColor.getValue(); + final int bgAlpha = mBackgroundOpacity.getValue(); + final int argb; + if (Color.alpha(bgColor) == 0) { + argb = Color.alpha(bgAlpha); + } else { + argb = bgColor & 0x00FFFFFF | bgAlpha & 0xFF000000; + } + Settings.Secure.putInt( + cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR, argb); + } else if (mEdgeColor == preference) { + Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR, value); + } else if (mPreset == preference) { + Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET, value); + } else if (mEdgeType == preference) { + Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE, value); + } + + refreshPreviewText(); + } + + @Override + public boolean onPreferenceChange(Preference preference, Object value) { + final ContentResolver cr = getActivity().getContentResolver(); + if (mTypeface == preference) { + Settings.Secure.putString( + cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE, (String) value); + } else if (mFontSize == preference) { + Settings.Secure.putFloat( + cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_FONT_SIZE, + Float.parseFloat((String) value)); + } else if (mLocale == preference) { + Settings.Secure.putString( + cr, Settings.Secure.ACCESSIBILITY_CAPTIONING_LOCALE, (String) value); + } + + refreshPreviewText(); + return true; + } +} diff --git a/src/com/android/settings/accessibility/CaptioningTextView.java b/src/com/android/settings/accessibility/CaptioningTextView.java new file mode 100644 index 0000000..7bb677e --- /dev/null +++ b/src/com/android/settings/accessibility/CaptioningTextView.java @@ -0,0 +1,309 @@ +/* + * Copyright (C) 2013 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 com.android.settings.accessibility; + +import android.content.ContentResolver; +import android.content.Context; +import android.content.res.ColorStateList; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Paint.Cap; +import android.graphics.Paint.Join; +import android.graphics.Paint.Style; +import android.os.Parcel; +import android.support.v4.view.ViewCompat; +import android.text.Editable; +import android.text.ParcelableSpan; +import android.text.TextPaint; +import android.text.TextUtils; +import android.text.style.CharacterStyle; +import android.text.style.UpdateAppearance; +import android.util.AttributeSet; +import android.view.accessibility.CaptioningManager; +import android.view.accessibility.CaptioningManager.CaptionStyle; +import android.widget.TextView; + +public class CaptioningTextView extends TextView { + private MutableBackgroundColorSpan mBackgroundSpan; + private ColorStateList mOutlineColorState; + private float mOutlineWidth; + private int mOutlineColor; + + private int mEdgeType = CaptionStyle.EDGE_TYPE_NONE; + private int mEdgeColor = Color.TRANSPARENT; + private float mEdgeWidth = 0; + + private boolean mHasBackground = false; + + public CaptioningTextView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + public CaptioningTextView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public CaptioningTextView(Context context) { + super(context); + } + + public void applyStyleAndFontSize(int styleId) { + final Context context = mContext; + final ContentResolver cr = context.getContentResolver(); + final CaptionStyle style; + if (styleId == CaptionStyle.PRESET_CUSTOM) { + style = CaptionStyle.getCustomStyle(cr); + } else { + style = CaptionStyle.PRESETS[styleId]; + } + + setTextColor(style.foregroundColor); + setBackgroundColor(style.backgroundColor); + setTypeface(style.getTypeface()); + + // Clears all outlines. + applyEdge(style.edgeType, style.edgeColor, 4.0f); + + final float fontSize = CaptioningManager.getFontSize(cr); + if (fontSize != 0) { + setTextSize(fontSize); + } + } + + /** + * Applies an edge preset using a combination of {@link #setOutlineLayer} + * and {@link #setShadowLayer}. Any subsequent calls to either of these + * methods will invalidate the applied preset. + * + * @param type Type of edge to apply, one of: + * <ul> + * <li>{@link CaptionStyle#EDGE_TYPE_NONE} + * <li>{@link CaptionStyle#EDGE_TYPE_OUTLINE} + * <li>{@link CaptionStyle#EDGE_TYPE_DROP_SHADOW} + * </ul> + * @param color Edge color as a packed 32-bit ARGB color. + * @param width Width of the edge in pixels. + */ + public void applyEdge(int type, int color, float width) { + if (mEdgeType != type || mEdgeColor != color || mEdgeWidth != width) { + final int textColor = getTextColors().getDefaultColor(); + switch (type) { + case CaptionStyle.EDGE_TYPE_DROP_SHADOW: + setOutlineLayer(0, 0); + super.setShadowLayer(width, width, width, color); + break; + case CaptionStyle.EDGE_TYPE_OUTLINE: + setOutlineLayer(width, color); + super.setShadowLayer(0, 0, 0, 0); + break; + default: + super.setShadowLayer(0, 0, 0, 0); + setOutlineLayer(0, 0); + } + + mEdgeType = type; + mEdgeColor = color; + mEdgeWidth = width; + } + } + + @Override + public void setShadowLayer(float radius, float dx, float dy, int color) { + mEdgeType = CaptionStyle.EDGE_TYPE_NONE; + + super.setShadowLayer(radius, dx, dy, color); + } + + /** + * Gives the text an outline of the specified pixel width and color. + */ + public void setOutlineLayer(float width, int color) { + width *= 2.0f; + + mEdgeType = CaptionStyle.EDGE_TYPE_NONE; + + if (mOutlineColor != color || mOutlineWidth != width) { + mOutlineColorState = ColorStateList.valueOf(color); + mOutlineColor = color; + mOutlineWidth = width; + invalidate(); + + // TODO: Remove after display list bug is fixed. + if (width > 0 && Color.alpha(color) != 0) { + setLayerType(ViewCompat.LAYER_TYPE_SOFTWARE, null); + } else { + setLayerType(ViewCompat.LAYER_TYPE_HARDWARE, null); + } + } + } + + /** + * @return the color of the outline layer + * @see #setOutlineLayer(float, int) + */ + public int getOutlineColor() { + return mOutlineColor; + } + + /** + * @return the width of the outline layer + * @see #setOutlineLayer(float, int) + */ + public float getOutlineWidth() { + return mOutlineWidth; + } + + @Override + public Editable getEditableText() { + final CharSequence text = getText(); + if (text instanceof Editable) { + return (Editable) text; + } + + setText(text, BufferType.EDITABLE); + return (Editable) getText(); + } + + @Override + public void setBackgroundColor(int color) { + if (Color.alpha(color) == 0) { + if (mHasBackground) { + mHasBackground = false; + getEditableText().removeSpan(mBackgroundSpan); + } + } else { + if (mBackgroundSpan == null) { + mBackgroundSpan = new MutableBackgroundColorSpan(color); + } else { + mBackgroundSpan.setColor(color); + } + + if (mHasBackground) { + invalidate(); + } else { + mHasBackground = true; + getEditableText().setSpan(mBackgroundSpan, 0, length(), 0); + } + } + } + + @Override + protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) { + super.onTextChanged(text, start, lengthBefore, lengthAfter); + + if (mBackgroundSpan != null) { + getEditableText().setSpan(mBackgroundSpan, 0, lengthAfter, 0); + } + } + + @Override + protected void onDraw(Canvas c) { + if (mOutlineWidth > 0 && Color.alpha(mOutlineColor) > 0) { + final TextPaint textPaint = getPaint(); + final Paint.Style previousStyle = textPaint.getStyle(); + final ColorStateList previousColors = getTextColors(); + textPaint.setStyle(Style.STROKE); + textPaint.setStrokeWidth(mOutlineWidth); + textPaint.setStrokeCap(Cap.ROUND); + textPaint.setStrokeJoin(Join.ROUND); + + setTextColor(mOutlineColorState); + + // Remove the shadow. + final float shadowRadius = getShadowRadius(); + final float shadowDx = getShadowDx(); + final float shadowDy = getShadowDy(); + final int shadowColor = getShadowColor(); + if (shadowRadius > 0) { + setShadowLayer(0, 0, 0, 0); + } + + // Draw outline and background only. + super.onDraw(c); + + // Restore the shadow. + if (shadowRadius > 0) { + setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor); + } + + // Restore original settings. + textPaint.setStyle(previousStyle); + setTextColor(previousColors); + + // Remove the background. + final int color; + if (mBackgroundSpan != null) { + color = mBackgroundSpan.getBackgroundColor(); + mBackgroundSpan.setColor(Color.TRANSPARENT); + } else { + color = 0; + } + + // Draw foreground only. + super.onDraw(c); + + // Restore the background. + if (mBackgroundSpan != null) { + mBackgroundSpan.setColor(color); + } + } else { + super.onDraw(c); + } + } + + public static class MutableBackgroundColorSpan extends CharacterStyle + implements UpdateAppearance, ParcelableSpan { + private int mColor; + + public MutableBackgroundColorSpan(int color) { + mColor = color; + } + + public MutableBackgroundColorSpan(Parcel src) { + mColor = src.readInt(); + } + + public void setColor(int color) { + mColor = color; + } + + @Override + public int getSpanTypeId() { + return TextUtils.BACKGROUND_COLOR_SPAN; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(mColor); + } + + public int getBackgroundColor() { + return mColor; + } + + @Override + public void updateDrawState(TextPaint ds) { + ds.bgColor = mColor; + } + } +} diff --git a/src/com/android/settings/accessibility/ColorPreference.java b/src/com/android/settings/accessibility/ColorPreference.java new file mode 100644 index 0000000..68af6b2 --- /dev/null +++ b/src/com/android/settings/accessibility/ColorPreference.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2013 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 com.android.settings.accessibility; + +import android.content.Context; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import com.android.settings.R; + +/** + * Grid preference that allows the user to pick a color from a predefined set of + * colors. Optionally shows a preview in the preference item. + */ +public class ColorPreference extends ListDialogPreference { + private ColorDrawable mPreviewColor; + private boolean mPreviewEnabled; + + public ColorPreference(Context context, AttributeSet attrs) { + super(context, attrs); + + setDialogLayoutResource(R.layout.grid_picker_dialog); + setListItemLayoutResource(R.layout.color_picker_item); + } + + /** + * @param enabled whether to show a preview in the preference item + */ + public void setPreviewEnabled(boolean enabled) { + if (mPreviewEnabled != enabled) { + mPreviewEnabled = enabled; + + if (enabled) { + setWidgetLayoutResource(R.layout.preference_color); + } else { + setWidgetLayoutResource(0); + } + } + } + + @Override + public boolean shouldDisableDependents() { + return getValue() == Color.TRANSPARENT || super.shouldDisableDependents(); + } + + @Override + protected void onBindView(View view) { + super.onBindView(view); + + if (mPreviewEnabled) { + final ImageView previewImage = (ImageView) view.findViewById(R.id.color_preview); + final int argb = getValue(); + if (Color.alpha(argb) < 255) { + previewImage.setBackgroundResource(R.drawable.transparency_tileable); + } else { + previewImage.setBackground(null); + } + + if (mPreviewColor == null) { + mPreviewColor = new ColorDrawable(argb); + previewImage.setImageDrawable(mPreviewColor); + } else { + mPreviewColor.setColor(argb); + } + + final CharSequence summary = getSummary(); + if (!TextUtils.isEmpty(summary)) { + previewImage.setContentDescription(summary); + } else { + previewImage.setContentDescription(null); + } + + previewImage.setAlpha(isEnabled() ? 1f : 0.2f); + } + } + + @Override + protected void onBindListItem(View view, int index) { + final int argb = getValueAt(index); + final int alpha = Color.alpha(argb); + + final ImageView swatch = (ImageView) view.findViewById(R.id.color_swatch); + if (alpha < 255) { + swatch.setBackgroundResource(R.drawable.transparency_tileable); + } else { + swatch.setBackground(null); + } + + final Drawable foreground = swatch.getDrawable(); + if (foreground instanceof ColorDrawable) { + ((ColorDrawable) foreground).setColor(argb); + } else { + swatch.setImageDrawable(new ColorDrawable(argb)); + } + + final CharSequence title = getTitleAt(index); + if (title != null) { + final TextView summary = (TextView) view.findViewById(R.id.summary); + summary.setText(title); + } + } +} diff --git a/src/com/android/settings/accessibility/EdgeTypePreference.java b/src/com/android/settings/accessibility/EdgeTypePreference.java new file mode 100644 index 0000000..d0dee1d --- /dev/null +++ b/src/com/android/settings/accessibility/EdgeTypePreference.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2013 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 com.android.settings.accessibility; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Color; +import android.util.AttributeSet; +import android.view.View; +import android.view.accessibility.CaptioningManager; +import android.view.accessibility.CaptioningManager.CaptionStyle; +import android.widget.TextView; + +import com.android.settings.R; + +/** + * Grid preference that allows the user to pick a captioning edge type. + */ +public class EdgeTypePreference extends ListDialogPreference { + public EdgeTypePreference(Context context, AttributeSet attrs) { + super(context, attrs); + + final Resources res = context.getResources(); + setValues(res.getIntArray(R.array.captioning_edge_type_selector_values)); + setTitles(res.getStringArray(R.array.captioning_edge_type_selector_titles)); + setDialogLayoutResource(R.layout.grid_picker_dialog); + setListItemLayoutResource(R.layout.preset_picker_item); + } + + @Override + public boolean shouldDisableDependents() { + return getValue() == CaptionStyle.EDGE_TYPE_NONE || super.shouldDisableDependents(); + } + + @Override + protected void onBindListItem(View view, int index) { + final float fontSize = CaptioningManager.getFontSize(getContext().getContentResolver()); + final CaptioningTextView preview = (CaptioningTextView) view.findViewById(R.id.preview); + preview.setTextColor(Color.WHITE); + preview.setBackgroundColor(Color.TRANSPARENT); + preview.setTextSize(fontSize); + + final int value = getValueAt(index); + preview.applyEdge(value, Color.BLACK, 4.0f); + + final CharSequence title = getTitleAt(index); + if (title != null) { + final TextView summary = (TextView) view.findViewById(R.id.summary); + summary.setText(title); + } + } +} diff --git a/src/com/android/settings/accessibility/ListDialogPreference.java b/src/com/android/settings/accessibility/ListDialogPreference.java new file mode 100644 index 0000000..a252454 --- /dev/null +++ b/src/com/android/settings/accessibility/ListDialogPreference.java @@ -0,0 +1,322 @@ +/* + * Copyright (C) 2013 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 com.android.settings.accessibility; + +import android.app.AlertDialog.Builder; +import android.app.Dialog; +import android.content.Context; +import android.content.res.TypedArray; +import android.os.Parcel; +import android.os.Parcelable; +import android.preference.DialogPreference; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AbsListView; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.BaseAdapter; + +/** + * Abstract dialog preference that displays a set of values and optional titles. + */ +public abstract class ListDialogPreference extends DialogPreference { + private CharSequence[] mEntryTitles; + private int[] mEntryValues; + + private OnValueChangedListener mOnValueChangedListener; + + /** The layout resource to use for grid items. */ + private int mListItemLayout; + + /** The current value of this preference. */ + private int mValue; + + /** The index within the value set of the current value. */ + private int mValueIndex; + + /** Whether the value had been set using {@link #setValue}. */ + private boolean mValueSet; + + public ListDialogPreference(Context context, AttributeSet attrs) { + super(context, attrs); + } + + /** + * Sets a listened to invoke when the value of this preference changes. + * + * @param listener the listener to invoke + */ + public void setOnValueChangedListener(OnValueChangedListener listener) { + mOnValueChangedListener = listener; + } + + /** + * Sets the layout to use for grid items. + * + * @param layoutResId the layout to use for displaying grid items + */ + public void setListItemLayoutResource(int layoutResId) { + mListItemLayout = layoutResId; + } + + /** + * Sets the list of item values. Values must be distinct. + * + * @param values the list of item values + */ + public void setValues(int[] values) { + mEntryValues = values; + } + + /** + * Sets the list of item titles. May be null if no titles are specified, or + * may be shorter than the list of values to leave some titles unspecified. + * + * @param titles the list of item titles + */ + public void setTitles(CharSequence[] titles) { + mEntryTitles = titles; + } + + /** + * Populates a list item view with data for the specified index. + * + * @param view the view to populate + * @param index the index for which to populate the view + * @see #setListItemLayoutResource(int) + * @see #getValueAt(int) + * @see #getTitleAt(int) + */ + protected abstract void onBindListItem(View view, int index); + + /** + * @return the title at the specified index, or null if none specified + */ + protected CharSequence getTitleAt(int index) { + if (mEntryTitles == null || mEntryTitles.length <= index) { + return null; + } + + return mEntryTitles[index]; + } + + /** + * @return the value at the specified index + */ + protected int getValueAt(int index) { + return mEntryValues[index]; + } + + @Override + public CharSequence getSummary() { + if (mValueIndex >= 0) { + return getTitleAt(mValueIndex); + } + + return null; + } + + @Override + protected void onPrepareDialogBuilder(Builder builder) { + super.onPrepareDialogBuilder(builder); + + final Context context = getContext(); + final int dialogLayout = getDialogLayoutResource(); + final View picker = LayoutInflater.from(context).inflate(dialogLayout, null); + final ListPreferenceAdapter adapter = new ListPreferenceAdapter(); + final AbsListView list = (AbsListView) picker.findViewById(android.R.id.list); + list.setAdapter(adapter); + list.setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(AdapterView<?> adapter, View v, int position, long id) { + if (callChangeListener((int) id)) { + setValue((int) id); + } + + final Dialog dialog = getDialog(); + if (dialog != null) { + dialog.dismiss(); + } + } + }); + + // Set initial selection. + final int selectedPosition = getIndexForValue(mValue); + if (selectedPosition != AbsListView.INVALID_POSITION) { + list.setSelection(selectedPosition); + } + + builder.setView(picker); + builder.setPositiveButton(null, null); + } + + /** + * @return the index of the specified value within the list of entry values, + * or {@link AbsListView#INVALID_POSITION} if not found + */ + protected int getIndexForValue(int value) { + final int[] values = mEntryValues; + final int count = values.length; + for (int i = 0; i < count; i++) { + if (values[i] == value) { + return i; + } + } + + return AbsListView.INVALID_POSITION; + } + + /** + * Sets the current value. If the value exists within the set of entry + * values, updates the selection index. + * + * @param value the value to set + */ + public void setValue(int value) { + final boolean changed = mValue != value; + if (changed || !mValueSet) { + mValue = value; + mValueIndex = getIndexForValue(value); + mValueSet = true; + persistInt(value); + if (changed) { + notifyDependencyChange(shouldDisableDependents()); + notifyChanged(); + } + if (mOnValueChangedListener != null) { + mOnValueChangedListener.onValueChanged(this, value); + } + } + } + + /** + * @return the current value + */ + public int getValue() { + return mValue; + } + + @Override + protected Object onGetDefaultValue(TypedArray a, int index) { + return a.getInt(index, 0); + } + + @Override + protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { + setValue(restoreValue ? getPersistedInt(mValue) : (Integer) defaultValue); + } + + @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.value = getValue(); + 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()); + setValue(myState.value); + } + + private class ListPreferenceAdapter extends BaseAdapter { + private LayoutInflater mInflater; + + @Override + public int getCount() { + return mEntryValues.length; + } + + @Override + public Integer getItem(int position) { + return mEntryValues[position]; + } + + @Override + public long getItemId(int position) { + return mEntryValues[position]; + } + + @Override + public boolean hasStableIds() { + return true; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + if (convertView == null) { + if (mInflater == null) { + mInflater = LayoutInflater.from(parent.getContext()); + } + convertView = mInflater.inflate(mListItemLayout, parent, false); + } + onBindListItem(convertView, position); + return convertView; + } + } + + private static class SavedState extends BaseSavedState { + public int value; + + public SavedState(Parcel source) { + super(source); + value = source.readInt(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeInt(value); + } + + public SavedState(Parcelable superState) { + super(superState); + } + + @SuppressWarnings({ "hiding", "unused" }) + public static final Creator<SavedState> CREATOR = new Creator<SavedState>() { + @Override + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + @Override + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + } + + public interface OnValueChangedListener { + public void onValueChanged(ListDialogPreference preference, int value); + } +} diff --git a/src/com/android/settings/accessibility/LocalePreference.java b/src/com/android/settings/accessibility/LocalePreference.java new file mode 100644 index 0000000..41cb1e5 --- /dev/null +++ b/src/com/android/settings/accessibility/LocalePreference.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2013 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 com.android.settings.accessibility; + +import android.content.Context; +import android.content.res.Resources; +import android.preference.ListPreference; +import android.util.AttributeSet; + +import com.android.settings.R; + +import java.text.Collator; +import java.util.Arrays; +import java.util.Locale; + +/** + * List preference that allows the user to pick a locale from the list of + * supported device locales. + */ +public class LocalePreference extends ListPreference { + public LocalePreference(Context context, AttributeSet attrs) { + super(context, attrs); + init(context); + } + + public LocalePreference(Context context) { + super(context); + init(context); + } + + public void init(Context context) { + final String[] systemLocales = Resources.getSystem().getAssets().getLocales(); + Arrays.sort(systemLocales); + + final Resources resources = context.getResources(); + final String[] specialLocaleCodes = resources.getStringArray( + com.android.internal.R.array.special_locale_codes); + final String[] specialLocaleNames = resources.getStringArray( + com.android.internal.R.array.special_locale_names); + + int finalSize = 0; + + final int origSize = systemLocales.length; + final LocaleInfo[] localeInfos = new LocaleInfo[origSize]; + for (int i = 0; i < origSize; i++) { + final String localeStr = systemLocales[i]; + final int len = localeStr.length(); + if (len != 5) { + continue; + } + + final String language = localeStr.substring(0, 2); + final String country = localeStr.substring(3, 5); + final Locale l = new Locale(language, country); + + if (finalSize == 0) { + localeInfos[finalSize++] = new LocaleInfo(l.getDisplayLanguage(l), l); + } else { + // check previous entry: + // same lang and a country -> upgrade to full name and + // insert ours with full name + // diff lang -> insert ours with lang-only name + final LocaleInfo previous = localeInfos[finalSize - 1]; + if (previous.locale.getLanguage().equals(language) + && !previous.locale.getLanguage().equals("zz")) { + previous.label = getDisplayName( + localeInfos[finalSize - 1].locale, specialLocaleCodes, + specialLocaleNames); + localeInfos[finalSize++] = new LocaleInfo(getDisplayName(l, + specialLocaleCodes, specialLocaleNames), l); + } else { + final String displayName; + if (localeStr.equals("zz_ZZ")) { + displayName = "[Developer] Accented English"; + } else if (localeStr.equals("zz_ZY")) { + displayName = "[Developer] Fake Bi-Directional"; + } else { + displayName = l.getDisplayLanguage(l); + } + localeInfos[finalSize++] = new LocaleInfo(displayName, l); + } + } + } + + final CharSequence[] entries = new CharSequence[finalSize + 1]; + final CharSequence[] entryValues = new CharSequence[finalSize + 1]; + Arrays.sort(localeInfos, 0, finalSize); + + entries[0] = resources.getString(R.string.locale_default); + entryValues[0] = ""; + + for (int i = 0; i < finalSize; i++) { + final LocaleInfo info = localeInfos[i]; + entries[i + 1] = info.toString(); + entryValues[i + 1] = info.locale.toString(); + } + + setEntries(entries); + setEntryValues(entryValues); + } + + private static String getDisplayName( + Locale l, String[] specialLocaleCodes, String[] specialLocaleNames) { + String code = l.toString(); + + for (int i = 0; i < specialLocaleCodes.length; i++) { + if (specialLocaleCodes[i].equals(code)) { + return specialLocaleNames[i]; + } + } + + return l.getDisplayName(l); + } + + private static class LocaleInfo implements Comparable<LocaleInfo> { + private static final Collator sCollator = Collator.getInstance(); + + public String label; + public Locale locale; + + public LocaleInfo(String label, Locale locale) { + this.label = label; + this.locale = locale; + } + + @Override + public String toString() { + return label; + } + + @Override + public int compareTo(LocaleInfo another) { + return sCollator.compare(this.label, another.label); + } + } +} diff --git a/src/com/android/settings/accessibility/PresetPreference.java b/src/com/android/settings/accessibility/PresetPreference.java new file mode 100644 index 0000000..cd01082 --- /dev/null +++ b/src/com/android/settings/accessibility/PresetPreference.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2013 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 com.android.settings.accessibility; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.view.accessibility.CaptioningManager.CaptionStyle; +import android.widget.TextView; + +import com.android.settings.R; + +public class PresetPreference extends ListDialogPreference { + public PresetPreference(Context context, AttributeSet attrs) { + super(context, attrs); + + setDialogLayoutResource(R.layout.grid_picker_dialog); + setListItemLayoutResource(R.layout.preset_picker_item); + } + + @Override + public boolean shouldDisableDependents() { + return getValue() != CaptionStyle.PRESET_CUSTOM + || super.shouldDisableDependents(); + } + + @Override + protected void onBindListItem(View view, int index) { + final CaptioningTextView previewText = (CaptioningTextView) view.findViewById( + R.id.preview); + final int value = getValueAt(index); + ToggleCaptioningPreferenceFragment.applyCaptionProperties(previewText, value); + + final CharSequence title = getTitleAt(index); + if (title != null) { + final TextView summary = (TextView) view.findViewById(R.id.summary); + summary.setText(title); + } + } +} diff --git a/src/com/android/settings/accessibility/ToggleCaptioningPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleCaptioningPreferenceFragment.java new file mode 100644 index 0000000..d0daf66 --- /dev/null +++ b/src/com/android/settings/accessibility/ToggleCaptioningPreferenceFragment.java @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2013 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 com.android.settings.accessibility; + +import android.app.ActionBar; +import android.app.Activity; +import android.app.Fragment; +import android.content.ContentResolver; +import android.content.Context; +import android.os.Bundle; +import android.preference.PreferenceFrameLayout; +import android.provider.Settings; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.accessibility.CaptioningManager; +import android.view.accessibility.CaptioningManager.CaptionStyle; + +import com.android.settings.R; +import com.android.settings.accessibility.ToggleSwitch.OnBeforeCheckedChangeListener; + +import java.util.Locale; + +public class ToggleCaptioningPreferenceFragment extends Fragment { + private CaptionPropertiesFragment mPropsFragment; + private CaptioningTextView mPreviewText; + + @Override + public View onCreateView( + LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + final View rootView = inflater.inflate(R.layout.captioning_preview, container, false); + + // We have to do this now because PreferenceFrameLayout looks at it + // only when the view is added. + if (container instanceof PreferenceFrameLayout) { + ((PreferenceFrameLayout.LayoutParams) rootView.getLayoutParams()).removeBorders = true; + } + + return rootView; + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + mPropsFragment = ((CaptionPropertiesFragment) getFragmentManager() + .findFragmentById(R.id.properties_fragment)); + mPropsFragment.setParent(this); + + mPreviewText = (CaptioningTextView) view.findViewById(R.id.preview_text); + + installActionBarToggleSwitch(); + refreshPreviewText(); + } + + public void refreshPreviewText() { + final CaptioningTextView preview = mPreviewText; + if (preview != null) { + final Activity activity = getActivity(); + final ContentResolver cr = activity.getContentResolver(); + final int styleId = CaptionStyle.getRawPreset(cr); + applyCaptionProperties(preview, styleId); + + final Locale locale = CaptioningManager.getLocale(cr); + if (locale != null) { + final CharSequence localizedText = AccessibilityUtils.getTextForLocale( + activity, locale, R.string.captioning_preview_text); + preview.setText(localizedText); + } + } + } + + public static void applyCaptionProperties(CaptioningTextView previewText, int styleId) { + previewText.applyStyleAndFontSize(styleId); + + final Context context = previewText.getContext(); + final ContentResolver cr = context.getContentResolver(); + final Locale locale = CaptioningManager.getLocale(cr); + if (locale != null) { + final CharSequence localizedText = AccessibilityUtils.getTextForLocale( + context, locale, R.string.captioning_preview_characters); + previewText.setText(localizedText); + } + } + + private void installActionBarToggleSwitch() { + final Activity activity = getActivity(); + final ToggleSwitch toggleSwitch = new ToggleSwitch(activity); + + final int padding = getResources().getDimensionPixelSize( + R.dimen.action_bar_switch_padding); + toggleSwitch.setPaddingRelative(0, 0, padding, 0); + + final ActionBar actionBar = activity.getActionBar(); + actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, ActionBar.DISPLAY_SHOW_CUSTOM); + + final ActionBar.LayoutParams params = new ActionBar.LayoutParams( + ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT, + Gravity.CENTER_VERTICAL | Gravity.END); + actionBar.setCustomView(toggleSwitch, params); + + final boolean enabled = CaptioningManager.isEnabled(getActivity().getContentResolver()); + mPropsFragment.getPreferenceScreen().setEnabled(enabled); + mPreviewText.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE); + toggleSwitch.setCheckedInternal(enabled); + toggleSwitch.setOnBeforeCheckedChangeListener(new OnBeforeCheckedChangeListener() { + @Override + public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked) { + toggleSwitch.setCheckedInternal(checked); + Settings.Secure.putInt(getActivity().getContentResolver(), + Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, checked ? 1 : 0); + mPropsFragment.getPreferenceScreen().setEnabled(checked); + mPreviewText.setVisibility(checked ? View.VISIBLE : View.INVISIBLE); + return false; + } + }); + } +} |