Adding settings screen for font size. Also factored out common

components from screen magnification settings screen.

Change-Id: I1828c7c0246f14493903172f2da7419fdc8e5f09
This commit is contained in:
Noah Wang
2015-12-15 09:05:30 -08:00
parent a164305d4d
commit e64cc267e7
12 changed files with 483 additions and 177 deletions

View File

@@ -0,0 +1,90 @@
<?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.
-->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="@dimen/font_size_preview_height"
android:background="?android:attr/colorBackgroundFloating"
android:elevation="2dp">
<view class="com.android.settings.TouchBlockingFrameLayout"
android:id="@+id/preview_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="@+id/current_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
android:padding="8dp"
android:theme="@android:style/Theme.Material"
android:background="?android:attr/colorBackgroundFloating"
android:textAppearance="@android:style/TextAppearance.Material.Caption"
android:textAllCaps="true"
android:elevation="2dp" />
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp">
<ImageView
android:id="@+id/smaller"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:src="@drawable/ic_remove_24dp"
android:tint="?android:attr/colorControlNormal"
android:tintMode="src_in"
android:scaleType="center"
android:focusable="true"
android:contentDescription="@string/font_size_make_smaller_desc" />
<SeekBar
android:id="@+id/seek_bar"
android:layout_width="0dp"
android:layout_height="48dp"
android:layout_weight="1"
style="@android:style/Widget.Material.SeekBar.Discrete"/>
<ImageView
android:id="@+id/larger"
android:layout_width="48dp"
android:layout_height="48dp"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:src="@drawable/ic_add_24dp"
android:tint="?android:attr/colorControlNormal"
android:tintMode="src_in"
android:scaleType="center"
android:focusable="true"
android:contentDescription="@string/font_size_make_larger_desc" />
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@@ -0,0 +1,39 @@
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/font_size_preview_text_title"
android:textAppearance="@android:style/TextAppearance.Material.Title"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/font_size_preview_text_subhead"
android:textAppearance="@android:style/TextAppearance.Material.Subhead"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/font_size_preview_text_body"
android:textAppearance="@android:style/TextAppearance.Material.Body1"/>
</LinearLayout>

View File

@@ -23,7 +23,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingTop="16dp" android:paddingTop="16dp"
android:paddingLeft="?android:attr/listPreferredItemPaddingStart" android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"> android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
<TextView <TextView
@@ -39,13 +39,13 @@
android:background="?android:attr/colorBackgroundFloating" android:background="?android:attr/colorBackgroundFloating"
android:elevation="2dp"> android:elevation="2dp">
<com.android.settings.display.TouchBlockingFrameLayout <view class="com.android.settings.TouchBlockingFrameLayout"
android:id="@+id/preview_frame" android:id="@+id/preview_frame"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
<TextView <TextView
android:id="@+id/current_density" android:id="@+id/current_label"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom" android:layout_gravity="center_horizontal|bottom"
@@ -78,7 +78,8 @@
android:id="@+id/seek_bar" android:id="@+id/seek_bar"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="48dp" android:layout_height="48dp"
android:layout_weight="1" /> android:layout_weight="1"
style="@android:style/Widget.Material.SeekBar.Discrete"/>
<ImageView <ImageView
android:id="@+id/larger" android:id="@+id/larger"

View File

@@ -270,4 +270,7 @@
<!-- Accessibility Settings --> <!-- Accessibility Settings -->
<dimen name="accessibility_layout_margin_start_end">24dp</dimen> <dimen name="accessibility_layout_margin_start_end">24dp</dimen>
<dimen name="accessibility_button_preference_padding_top_bottom">18dp</dimen> <dimen name="accessibility_button_preference_padding_top_bottom">18dp</dimen>
<!-- Accessibility, Font size -->
<dimen name="font_size_preview_height">240dp</dimen>
</resources> </resources>

View File

@@ -154,8 +154,16 @@
<!-- choice for the font size spinner --> <!-- choice for the font size spinner -->
<string name="large_font">Large</string> <string name="large_font">Large</string>
<!-- Description for the button that makes interface elements smaller. [CHAR_LIMIT=NONE] -->
<string name="font_size_make_smaller_desc">Make smaller</string>
<!-- Description for the button that makes interface elements larger. [CHAR_LIMIT=NONE] -->
<string name="font_size_make_larger_desc">Make larger</string>
<!-- Do not translate. label for font size preview. Does not need to be translated. --> <!-- Do not translate. label for font size preview. Does not need to be translated. -->
<string name="font_size_preview_text">Servez à ce monsieur une bière et des kiwis.</string> <string name="font_size_preview_text">Servez à ce monsieur une bière et des kiwis.</string>
<string name="font_size_preview_text_title" translatable="false">Twenty Thousand Leagues Under The Sea</string>
<string name="font_size_preview_text_subhead" translatable="false">Chapter 23: The Coral Kingdom</string>
<string name="font_size_preview_text_body" translatable="false">The next day I woke with my head singularly clear. To my great surprise, I was in my own room. My companions, no doubt, had been reinstated in their cabin, without having perceived it any more than I. Of what had passed during the night they were as ignorant as I was, and to penetrate this mystery I only reckoned upon the chances of the future.</string>
<!-- Button. Chosen when they want to save the chosen text size. --> <!-- Button. Chosen when they want to save the chosen text size. -->
<string name="font_size_save">OK</string> <string name="font_size_save">OK</string>

View File

@@ -43,6 +43,11 @@
android:key="screen_magnification_preference_screen" android:key="screen_magnification_preference_screen"
android:title="@string/accessibility_screen_magnification_title"/> android:title="@string/accessibility_screen_magnification_title"/>
<PreferenceScreen
android:fragment="com.android.settings.accessibility.ToggleFontSizePreferenceFragment"
android:key="font_size_preference_screen"
android:title="@string/title_font_size"/>
<PreferenceScreen <PreferenceScreen
android:fragment="com.android.settings.accessibility.ToggleAutoclickPreferenceFragment" android:fragment="com.android.settings.accessibility.ToggleAutoclickPreferenceFragment"
android:key="autoclick_preference_screen" android:key="autoclick_preference_screen"

View File

@@ -30,7 +30,7 @@
android:layout="@layout/preference_button" android:layout="@layout/preference_button"
android:title="@string/title_font_size" /> android:title="@string/title_font_size" />
<com.android.settings.DisplayDensityPreference <com.android.settings.display.ScreenZoomPreference
android:key="force_density_preference" android:key="force_density_preference"
android:layout="@layout/preference_button" android:layout="@layout/preference_button"
settings:keywords="@string/screen_zoom_keywords" settings:keywords="@string/screen_zoom_keywords"

View File

@@ -33,6 +33,7 @@ public abstract class InstrumentedFragment extends PreferenceFragment {
public static final int CONFIGURE_NOTIFICATION = UNDECLARED + 3; public static final int CONFIGURE_NOTIFICATION = UNDECLARED + 3;
public static final int CONFIGURE_WIFI = UNDECLARED + 4; public static final int CONFIGURE_WIFI = UNDECLARED + 4;
public static final int DISPLAY_SCREEN_ZOOM = UNDECLARED + 5; public static final int DISPLAY_SCREEN_ZOOM = UNDECLARED + 5;
public static final int ACCESSIBILITY_FONT_SIZE = UNDECLARED + 6;
/** /**
* Declare the view of this category. * Declare the view of this category.

View File

@@ -0,0 +1,222 @@
/*
* 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 com.android.settings;
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
/**
* Preference fragment shows a preview and a seek bar to adjust a specific settings.
*/
public abstract class PreviewSeekBarPreferenceFragment extends SettingsPreferenceFragment {
/** List of entries corresponding the settings being set. */
protected String[] mEntries;
/** Index of the entry corresponding to initial value of the settings. */
protected int mInitialIndex;
/** Index of the entry corresponding to current value of the settings. */
protected int mCurrentIndex;
/** Resource id of the layout for this preference fragment. */
protected int mActivityLayoutResId;
/** Resource id of the layout that defines the contents instide preview screen. */
protected int mPreviewSampleResId;
/** Duration to use when cross-fading between previews. */
private static final long CROSS_FADE_DURATION_MS = 400;
/** Interpolator to use when cross-fading between previews. */
private static final Interpolator FADE_IN_INTERPOLATOR = new DecelerateInterpolator();
/** Interpolator to use when cross-fading between previews. */
private static final Interpolator FADE_OUT_INTERPOLATOR = new AccelerateInterpolator();
private ViewGroup mPreviewFrame;
private TextView mLabel;
private View mLarger;
private View mSmaller;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View root = super.onCreateView(inflater, container, savedInstanceState);
final ViewGroup listContainer = (ViewGroup) root.findViewById(android.R.id.list_container);
listContainer.removeAllViews();
final View content = inflater.inflate(mActivityLayoutResId, listContainer, false);
listContainer.addView(content);
mLabel = (TextView) content.findViewById(R.id.current_label);
// The maximum SeekBar value always needs to be non-zero. If there's
// only one available value, we'll handle this by disabling the
// seek bar.
final int max = Math.max(1, mEntries.length - 1);
final SeekBar seekBar = (SeekBar) content.findViewById(R.id.seek_bar);
seekBar.setMax(max);
seekBar.setProgress(mInitialIndex);
seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
setPreviewLayer(progress, true);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
});
mSmaller = content.findViewById(R.id.smaller);
mSmaller.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
final int progress = seekBar.getProgress();
if (progress > 0) {
seekBar.setProgress(progress - 1, true);
}
}
});
mLarger = content.findViewById(R.id.larger);
mLarger.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
final int progress = seekBar.getProgress();
if (progress < seekBar.getMax()) {
seekBar.setProgress(progress + 1, true);
}
}
});
if (mEntries.length == 1) {
// The larger and smaller buttons will be disabled when we call
// setPreviewLayer() later in this method.
seekBar.setEnabled(false);
}
mPreviewFrame = (FrameLayout) content.findViewById(R.id.preview_frame);
// Populate the sample layouts.
final Context context = getContext();
final Configuration origConfig = context.getResources().getConfiguration();
for (int i = 0; i < mEntries.length; ++i) {
final Configuration config = createConfig(origConfig, i);
// Create a new configuration for the specified value. It won't
// have any theme set, so manually apply the current theme.
final Context configContext = context.createConfigurationContext(config);
configContext.setTheme(context.getThemeResId());
final LayoutInflater configInflater = LayoutInflater.from(configContext);
final View sampleView = configInflater.inflate(mPreviewSampleResId, mPreviewFrame, false);
sampleView.setAlpha(0);
sampleView.setVisibility(View.INVISIBLE);
mPreviewFrame.addView(sampleView);
}
setPreviewLayer(mInitialIndex, false);
return root;
}
@Override
public void onDetach() {
super.onDetach();
// This will commit the change SLIGHTLY after the activity has
// finished, which could be considered a feature or a bug...
commit();
}
/**
* Creates new configuration based on the current position of the SeekBar.
*/
protected abstract Configuration createConfig(Configuration origConfig, int index);
private void setPreviewLayer(int index, boolean animate) {
mLabel.setText(mEntries[index]);
if (mCurrentIndex >= 0) {
final View lastLayer = mPreviewFrame.getChildAt(mCurrentIndex);
if (animate) {
lastLayer.animate()
.alpha(0)
.setInterpolator(FADE_OUT_INTERPOLATOR)
.setDuration(CROSS_FADE_DURATION_MS)
.withEndAction(new Runnable() {
@Override
public void run() {
lastLayer.setVisibility(View.INVISIBLE);
}
});
} else {
lastLayer.setAlpha(0);
lastLayer.setVisibility(View.INVISIBLE);
}
}
final View nextLayer = mPreviewFrame.getChildAt(index);
if (animate) {
nextLayer.animate()
.alpha(1)
.setInterpolator(FADE_IN_INTERPOLATOR)
.setDuration(CROSS_FADE_DURATION_MS)
.withStartAction(new Runnable() {
@Override
public void run() {
nextLayer.setVisibility(View.VISIBLE);
}
});
} else {
nextLayer.setVisibility(View.VISIBLE);
nextLayer.setAlpha(1);
}
mSmaller.setEnabled(index > 0);
mLarger.setEnabled(index < mEntries.length - 1);
mCurrentIndex = index;
}
/**
* Persists the selected value and sends a configuration change.
*/
protected abstract void commit();
}

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package com.android.settings.display; package com.android.settings;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.content.Context; import android.content.Context;

View File

@@ -0,0 +1,97 @@
/*
* 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 com.android.settings.accessibility;
import com.android.settings.InstrumentedFragment;
import com.android.settings.R;
import com.android.settings.PreviewSeekBarPreferenceFragment;
import android.annotation.Nullable;
import android.app.ActivityManagerNative;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
/**
* Preference fragment used to control font size.
*/
public class ToggleFontSizePreferenceFragment extends PreviewSeekBarPreferenceFragment {
private static final String LOG_TAG = "ToggleFontSizePreferenceFragment";
private float[] mValues;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActivityLayoutResId = R.layout.font_size_activity;
mPreviewSampleResId = R.layout.font_size_preview;
Resources res = getContext().getResources();
// Mark the appropriate item in the preferences list.
final Configuration origConfig = res.getConfiguration();
mEntries = res.getStringArray(R.array.entries_font_size);
final String[] strEntryValues = res.getStringArray(R.array.entryvalues_font_size);
mInitialIndex = floatToIndex(origConfig.fontScale, strEntryValues);
mValues = new float[strEntryValues.length];
for (int i = 0; i < strEntryValues.length; ++i) {
mValues[i] = Float.parseFloat(strEntryValues[i]);
}
}
@Override
protected Configuration createConfig(Configuration origConfig, int index) {
// Populate the sample layouts.
final Configuration config = new Configuration(origConfig);
config.fontScale = mValues[index];
return config;
}
/**
* Persists the selected font size and sends a configuration change.
*/
@Override
protected void commit() {
Configuration config = getContext().getResources().getConfiguration();
config.fontScale = mValues[mCurrentIndex];
try {
ActivityManagerNative.getDefault().updatePersistentConfiguration(config);
} catch (RemoteException e) {
Log.w(LOG_TAG, "Unable to save font size setting");
}
}
@Override
protected int getMetricsCategory() {
return InstrumentedFragment.ACCESSIBILITY_FONT_SIZE;
}
private int floatToIndex(float val, String[] indices) {
float lastVal = Float.parseFloat(indices[0]);
for (int i=1; i<indices.length; i++) {
float thisVal = Float.parseFloat(indices[i]);
if (val < (lastVal + (thisVal-lastVal)*.5f)) {
return i-1;
}
lastVal = thisVal;
}
return indices.length-1;
}
}

View File

@@ -18,7 +18,7 @@ package com.android.settings.display;
import com.android.settings.InstrumentedFragment; import com.android.settings.InstrumentedFragment;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment; import com.android.settings.PreviewSeekBarPreferenceFragment;
import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable; import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw; import com.android.settings.search.SearchIndexableRaw;
@@ -29,17 +29,6 @@ import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Bundle; import android.os.Bundle;
import android.view.Display; import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -47,32 +36,17 @@ import java.util.List;
/** /**
* Preference fragment used to control screen zoom. * Preference fragment used to control screen zoom.
*/ */
public class ScreenZoomSettings extends SettingsPreferenceFragment implements Indexable { public class ScreenZoomSettings extends PreviewSeekBarPreferenceFragment implements Indexable {
/** Duration to use when cross-fading between previews. */
private static final long CROSS_FADE_DURATION_MS = 400;
/** Interpolator to use when cross-fading between previews. */
private static final Interpolator FADE_IN_INTERPOLATOR = new DecelerateInterpolator();
/** Interpolator to use when cross-fading between previews. */
private static final Interpolator FADE_OUT_INTERPOLATOR = new AccelerateInterpolator();
private ViewGroup mPreviewFrame;
private TextView mLabel;
private View mLarger;
private View mSmaller;
private String[] mEntries;
private int[] mValues;
private int mNormalDensity; private int mNormalDensity;
private int mInitialIndex; private int[] mValues;
private int mCurrentIndex;
@Override @Override
public void onCreate(@Nullable Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mActivityLayoutResId = R.layout.screen_zoom_activity;
mPreviewSampleResId = R.layout.screen_zoom_preview;
final DisplayDensityUtils density = new DisplayDensityUtils(getContext()); final DisplayDensityUtils density = new DisplayDensityUtils(getContext());
final int initialIndex = density.getCurrentIndex(); final int initialIndex = density.getCurrentIndex();
@@ -94,152 +68,18 @@ public class ScreenZoomSettings extends SettingsPreferenceFragment implements In
} }
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, protected Configuration createConfig(Configuration origConfig, int index) {
Bundle savedInstanceState) {
final View root = super.onCreateView(inflater, container, savedInstanceState);
final ViewGroup list_container = (ViewGroup) root.findViewById(android.R.id.list_container);
list_container.removeAllViews();
final View content = inflater.inflate(R.layout.screen_zoom_activity, list_container, false);
list_container.addView(content);
mLabel = (TextView) content.findViewById(R.id.current_density);
// The maximum SeekBar value always needs to be non-zero. If there's
// only one available zoom level, we'll handle this by disabling the
// seek bar.
final int max = Math.max(1, mValues.length - 1);
final SeekBar seekBar = (SeekBar) content.findViewById(R.id.seek_bar);
seekBar.setMax(max);
seekBar.setProgress(mInitialIndex);
seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
setPreviewLayer(progress, true);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
});
mSmaller = content.findViewById(R.id.smaller);
mSmaller.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
final int progress = seekBar.getProgress();
if (progress > 0) {
seekBar.setProgress(progress - 1, true);
}
}
});
mLarger = content.findViewById(R.id.larger);
mLarger.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
final int progress = seekBar.getProgress();
if (progress < seekBar.getMax()) {
seekBar.setProgress(progress + 1, true);
}
}
});
if (mValues.length == 1) {
// The larger and smaller buttons will be disabled when we call
// setPreviewLayer() later in this method.
seekBar.setEnabled(false);
}
mPreviewFrame = (FrameLayout) content.findViewById(R.id.preview_frame);
// Populate the sample layouts. // Populate the sample layouts.
final Context context = getContext(); final Configuration config = new Configuration(origConfig);
final Configuration origConfig = context.getResources().getConfiguration(); config.densityDpi = mValues[index];
for (int mValue : mValues) { return config;
final Configuration config = new Configuration(origConfig);
config.densityDpi = mValue;
// Create a new configuration for the specified density. It won't
// have any theme set, so manually apply the current theme.
final Context configContext = context.createConfigurationContext(config);
configContext.setTheme(context.getThemeResId());
final LayoutInflater configInflater = LayoutInflater.from(configContext);
final View sampleView = configInflater.inflate(
R.layout.screen_zoom_preview, mPreviewFrame, false);
sampleView.setAlpha(0);
sampleView.setVisibility(View.INVISIBLE);
mPreviewFrame.addView(sampleView);
}
setPreviewLayer(mInitialIndex, false);
return root;
}
@Override
public void onDetach() {
super.onDetach();
// This will adjust the density SLIGHTLY after the activity has
// finished, which could be considered a feature or a bug...
commit();
}
private void setPreviewLayer(int index, boolean animate) {
mLabel.setText(mEntries[index]);
if (mCurrentIndex >= 0) {
final View lastLayer = mPreviewFrame.getChildAt(mCurrentIndex);
if (animate) {
lastLayer.animate()
.alpha(0)
.setInterpolator(FADE_OUT_INTERPOLATOR)
.setDuration(CROSS_FADE_DURATION_MS)
.withEndAction(new Runnable() {
@Override
public void run() {
lastLayer.setVisibility(View.INVISIBLE);
}
});
} else {
lastLayer.setAlpha(0);
lastLayer.setVisibility(View.INVISIBLE);
}
}
final View nextLayer = mPreviewFrame.getChildAt(index);
if (animate) {
nextLayer.animate()
.alpha(1)
.setInterpolator(FADE_IN_INTERPOLATOR)
.setDuration(CROSS_FADE_DURATION_MS)
.withStartAction(new Runnable() {
@Override
public void run() {
nextLayer.setVisibility(View.VISIBLE);
}
});
} else {
nextLayer.setVisibility(View.VISIBLE);
nextLayer.setAlpha(1);
}
mSmaller.setEnabled(index > 0);
mLarger.setEnabled(index < mEntries.length - 1);
mCurrentIndex = index;
} }
/** /**
* Persists the selected density and sends a configuration change. * Persists the selected density and sends a configuration change.
*/ */
private void commit() { @Override
protected void commit() {
final int densityDpi = mValues[mCurrentIndex]; final int densityDpi = mValues[mCurrentIndex];
if (densityDpi == mNormalDensity) { if (densityDpi == mNormalDensity) {
DisplayDensityUtils.clearForcedDisplayDensity(Display.DEFAULT_DISPLAY); DisplayDensityUtils.clearForcedDisplayDensity(Display.DEFAULT_DISPLAY);