Merge "Implement Settings UI for Screen zoom preference"
This commit is contained in:
committed by
Android (Google) Code Review
commit
5d2e64a225
@@ -14,11 +14,12 @@
|
|||||||
~ limitations under the License
|
~ limitations under the License
|
||||||
-->
|
-->
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="24.0dp"
|
android:width="24dp"
|
||||||
android:height="24.0dp"
|
android:height="24dp"
|
||||||
android:viewportWidth="48.0"
|
android:viewportWidth="48"
|
||||||
android:viewportHeight="48.0">
|
android:viewportHeight="48"
|
||||||
|
android:tint="?android:attr/colorAccent">
|
||||||
<path
|
<path
|
||||||
android:fillColor="?android:attr/colorAccent"
|
android:fillColor="@android:color/white"
|
||||||
android:pathData="M38.0,26.0L26.0,26.0l0.0,12.0l-4.0,0.0L22.0,26.0L10.0,26.0l0.0,-4.0l12.0,0.0L22.0,10.0l4.0,0.0l0.0,12.0l12.0,0.0l0.0,4.0z"/>
|
android:pathData="M38,26L26,26l0,12l-4,0L22,26L10,26l0,-4l12,0L22,10l4,0l0,12l12,0l0,4.0z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
@@ -14,11 +14,11 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="24.0dp"
|
android:width="24dp"
|
||||||
android:height="24.0dp"
|
android:height="24dp"
|
||||||
android:viewportWidth="24.0"
|
android:viewportWidth="24"
|
||||||
android:viewportHeight="24.0">
|
android:viewportHeight="24">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#FFFFFFFF"
|
android:fillColor="@android:color/white"
|
||||||
android:pathData="M11.0,17.0l2.0,0.0l0.0,-6.0l-2.0,0.0l0.0,6.0zm1.0,-15.0C6.48,2.0 2.0,6.48 2.0,12.0s4.48,10.0 10.0,10.0 10.0,-4.48 10.0,-10.0S17.52,2.0 12.0,2.0zm0.0,18.0c-4.41,0.0 -8.0,-3.59 -8.0,-8.0s3.59,-8.0 8.0,-8.0 8.0,3.59 8.0,8.0 -3.59,8.0 -8.0,8.0zM11.0,9.0l2.0,0.0L13.0,7.0l-2.0,0.0l0.0,2.0z"/>
|
android:pathData="M11,17l2,0l0,-6l-2,0l0,6.0zm1,-15.0C6.48,2 2,6.48 2,12.0s4.48,10 10,10 10,-4.48 10,-10.0S17.52,2 12,2.0zm0,18.0c-4.41,0 -8,-3.59 -8,-8.0s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8.0zM11,9l2,0L13,7l-2,0l0,2.0z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
25
res/drawable/ic_remove_24dp.xml
Normal file
25
res/drawable/ic_remove_24dp.xml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<!--
|
||||||
|
~ 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
|
||||||
|
-->
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="48"
|
||||||
|
android:viewportHeight="48"
|
||||||
|
android:tint="?android:attr/colorAccent">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M38 26H10v-4h28v4z"/>
|
||||||
|
</vector>
|
22
res/drawable/screen_zoom_preview_action_background.xml
Normal file
22
res/drawable/screen_zoom_preview_action_background.xml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<size android:width="24dp"
|
||||||
|
android:height="24dp" />
|
||||||
|
<solid android:color="@android:color/white" />
|
||||||
|
</shape>
|
96
res/layout/screen_zoom_activity.xml
Normal file
96
res/layout/screen_zoom_activity.xml
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
<?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:paddingLeft="?android:attr/listPreferredItemPaddingStart"
|
||||||
|
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/screen_zoom_summary"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:textAppearance="@android:style/TextAppearance.Material.Subhead" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/screen_zoom_preview_height"
|
||||||
|
android:background="?android:attr/colorBackgroundFloating"
|
||||||
|
android:elevation="2dp">
|
||||||
|
|
||||||
|
<com.android.settings.display.TouchBlockingFrameLayout
|
||||||
|
android:id="@+id/preview_frame"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/current_density"
|
||||||
|
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/screen_zoom_make_smaller_desc" />
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/seek_bar"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_weight="1" />
|
||||||
|
|
||||||
|
<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/screen_zoom_make_larger_desc" />
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
85
res/layout/screen_zoom_preview.xml
Normal file
85
res/layout/screen_zoom_preview.xml
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
<?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">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?android:attr/actionBarSize"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:theme="?android:attr/actionBarTheme"
|
||||||
|
style="?android:attr/actionBarStyle">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:text="@string/screen_zoom_preview_title"
|
||||||
|
android:textAppearance="@android:style/TextAppearance.Material.Widget.ActionBar.Title" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
style="?android:attr/actionOverflowButtonStyle" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scrollbars="none"
|
||||||
|
android:background="?android:attr/colorBackgroundFloating">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@android:style/TextAppearance.Material.Subhead"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="@string/permissions_label" />
|
||||||
|
|
||||||
|
<include layout="@layout/screen_zoom_preview_item" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_marginLeft="62dp"
|
||||||
|
android:layout_marginRight="8dp"
|
||||||
|
android:background="#36000000" />
|
||||||
|
|
||||||
|
<include layout="@layout/screen_zoom_preview_item" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_marginLeft="62dp"
|
||||||
|
android:layout_marginRight="8dp"
|
||||||
|
android:background="#36000000" />
|
||||||
|
|
||||||
|
<include layout="@layout/screen_zoom_preview_item" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
|
</LinearLayout>
|
65
res/layout/screen_zoom_preview_item.xml
Normal file
65
res/layout/screen_zoom_preview_item.xml
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
<?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"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:padding="16dp"
|
||||||
|
tools:showIn="@layout/screen_zoom_preview">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/icon"
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:background="@drawable/screen_zoom_preview_action_background"
|
||||||
|
android:backgroundTint="?android:attr/colorAccent"
|
||||||
|
android:src="@drawable/ic_settings_32dp"
|
||||||
|
android:scaleType="center" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingStart="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/usage_access"
|
||||||
|
style="@android:style/TextAppearance.Material.Body1" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/summary"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/usage_access_description"
|
||||||
|
style="@android:style/TextAppearance.Material.Caption" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/action"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginLeft="24dp"
|
||||||
|
android:src="@drawable/ic_info"
|
||||||
|
android:tint="?android:attr/colorControlNormal"
|
||||||
|
android:tintMode="src_in"
|
||||||
|
android:scaleType="center" />
|
||||||
|
</LinearLayout>
|
@@ -48,4 +48,7 @@
|
|||||||
<!-- Fingerprint -->
|
<!-- Fingerprint -->
|
||||||
<item name="fingerprint_illustration_aspect_ratio" format="float" type="dimen">0.0</item>
|
<item name="fingerprint_illustration_aspect_ratio" format="float" type="dimen">0.0</item>
|
||||||
<dimen name="fingerprint_decor_padding_top">24dp</dimen>
|
<dimen name="fingerprint_decor_padding_top">24dp</dimen>
|
||||||
|
|
||||||
|
<!-- Display, Screen zoom -->
|
||||||
|
<dimen name="screen_zoom_preview_height">160dp</dimen>
|
||||||
</resources>
|
</resources>
|
||||||
|
@@ -252,4 +252,7 @@
|
|||||||
|
|
||||||
<!-- Button bar padding for unmount button. -->
|
<!-- Button bar padding for unmount button. -->
|
||||||
<dimen name="unmount_button_padding">8dp</dimen>
|
<dimen name="unmount_button_padding">8dp</dimen>
|
||||||
|
|
||||||
|
<!-- Display, Screen zoom -->
|
||||||
|
<dimen name="screen_zoom_preview_height">240dp</dimen>
|
||||||
</resources>
|
</resources>
|
||||||
|
@@ -6613,23 +6613,33 @@
|
|||||||
<!-- Description of setting that controls gesture to open camera by double tapping the power button [CHAR LIMIT=NONE] -->
|
<!-- Description of setting that controls gesture to open camera by double tapping the power button [CHAR LIMIT=NONE] -->
|
||||||
<string name="camera_double_tap_power_gesture_desc">Quickly open camera without unlocking your screen</string>
|
<string name="camera_double_tap_power_gesture_desc">Quickly open camera without unlocking your screen</string>
|
||||||
|
|
||||||
<!-- Title of setting that controls display scale (e.g. density). [CHAR LIMIT=40] -->
|
<!-- Title of setting that controls screen zoom (e.g. how large interface elements appear). [CHAR LIMIT=40] -->
|
||||||
<string name="force_density_preference_title">Display scale</string>
|
<string name="screen_zoom_title">Screen zoom</string>
|
||||||
<!-- Keywords for setting that controls display scale (e.g. density). [CHAR LIMIT=NONE] -->
|
<!-- Keywords for setting that controls screen zoom (e.g. how large interface elements appear). [CHAR LIMIT=NONE] -->
|
||||||
<string name="force_density_keywords">display density zoom scale scaling</string>
|
<string name="screen_zoom_keywords">display density screen zoom scale scaling</string>
|
||||||
<!-- Description for the display scale that makes interface elements small. [CHAR LIMIT=24] -->
|
|
||||||
<string name="force_density_summary_small">Small</string>
|
<string name="screen_zoom_summary">Choose how zoomed you want the screen using the slider below the preview image.</string>
|
||||||
<!-- Description for the device's default display scale. [CHAR LIMIT=24] -->
|
|
||||||
<string name="force_density_summary_normal">Normal</string>
|
<!-- Title of the screen zoom preview activity. -->
|
||||||
<!-- Description for the display scale that makes interface elements large. [CHAR LIMIT=24] -->
|
<string name="screen_zoom_preview_title">Preview</string>
|
||||||
<string name="force_density_summary_large">Large</string>
|
<!-- Description for the button that makes interface elements smaller. [CHAR_LIMIT=NONE] -->
|
||||||
<!-- Description for the display scale that makes interface elements larger. [CHAR LIMIT=24] -->
|
<string name="screen_zoom_make_smaller_desc">Make smaller</string>
|
||||||
<string name="force_density_summary_very_large">Larger</string>
|
<!-- Description for the button that makes interface elements larger. [CHAR_LIMIT=NONE] -->
|
||||||
<!-- Description for the display scale that makes interface elements largest. [CHAR LIMIT=24] -->
|
<string name="screen_zoom_make_larger_desc">Make larger</string>
|
||||||
<string name="force_density_summary_extremely_large">Largest</string>
|
|
||||||
<!-- Description for a custom display scale. This shows the requested display
|
<!-- Description for the screen zoom level that makes interface elements small. [CHAR LIMIT=24] -->
|
||||||
density in raw pixels per inch rather than computing a scale amount. [CHAR LIMIT=24] -->
|
<string name="screen_zoom_summary_small">Small</string>
|
||||||
<string name="force_density_summary_custom">Custom (<xliff:g id="densityDpi" example="160">%d</xliff:g>)</string>
|
<!-- Description for the device's default screen zoom level. [CHAR LIMIT=24] -->
|
||||||
|
<string name="screen_zoom_summary_normal">Normal</string>
|
||||||
|
<!-- Description for the screen zoom level that makes interface elements large. [CHAR LIMIT=24] -->
|
||||||
|
<string name="screen_zoom_summary_large">Large</string>
|
||||||
|
<!-- Description for the screen zoom level that makes interface elements larger. [CHAR LIMIT=24] -->
|
||||||
|
<string name="screen_zoom_summary_very_large">Larger</string>
|
||||||
|
<!-- Description for the screen zoom level that makes interface elements largest. [CHAR LIMIT=24] -->
|
||||||
|
<string name="screen_zoom_summary_extremely_large">Largest</string>
|
||||||
|
<!-- Description for a custom screen zoom level. This shows the requested display
|
||||||
|
density in raw pixels per inch rather than using a relative description. [CHAR LIMIT=24] -->
|
||||||
|
<string name="screen_zoom_summary_custom">Custom (<xliff:g id="densityDpi" example="160">%d</xliff:g>)</string>
|
||||||
|
|
||||||
<!-- Button to show all top-level settings items [CHAR LIMIT=20] -->
|
<!-- Button to show all top-level settings items [CHAR LIMIT=20] -->
|
||||||
<string name="see_all">See all</string>
|
<string name="see_all">See all</string>
|
||||||
|
@@ -99,12 +99,10 @@
|
|||||||
android:entries="@array/entries_font_size"
|
android:entries="@array/entries_font_size"
|
||||||
android:entryValues="@array/entryvalues_font_size" />
|
android:entryValues="@array/entryvalues_font_size" />
|
||||||
|
|
||||||
<com.android.settings.DisplayDensityPreference
|
<com.android.settings.display.ScreenZoomPreference
|
||||||
android:key="display_density"
|
android:key="screen_zoom"
|
||||||
android:title="@string/force_density_preference_title"
|
android:title="@string/screen_zoom_title"
|
||||||
android:summary="%s"
|
settings:keywords="@string/screen_zoom_keywords" />
|
||||||
settings:keywords="@string/force_density_keywords"
|
|
||||||
android:persistent="false" />
|
|
||||||
|
|
||||||
<com.android.settings.DropDownPreference
|
<com.android.settings.DropDownPreference
|
||||||
android:key="auto_rotate"
|
android:key="auto_rotate"
|
||||||
|
@@ -76,7 +76,6 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
|
|||||||
private static final String KEY_CAMERA_GESTURE = "camera_gesture";
|
private static final String KEY_CAMERA_GESTURE = "camera_gesture";
|
||||||
private static final String KEY_CAMERA_DOUBLE_TAP_POWER_GESTURE
|
private static final String KEY_CAMERA_DOUBLE_TAP_POWER_GESTURE
|
||||||
= "camera_double_tap_power_gesture";
|
= "camera_double_tap_power_gesture";
|
||||||
private static final String KEY_DISPLAY_DENSITY = "display_density";
|
|
||||||
|
|
||||||
private DropDownPreference mFontSizePref;
|
private DropDownPreference mFontSizePref;
|
||||||
|
|
||||||
@@ -214,9 +213,6 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
|
|||||||
mNightModePreference.setValue(String.valueOf(currentNightMode));
|
mNightModePreference.setValue(String.valueOf(currentNightMode));
|
||||||
mNightModePreference.setOnPreferenceChangeListener(this);
|
mNightModePreference.setOnPreferenceChangeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Preference displayDensity = findPreference(KEY_DISPLAY_DENSITY);
|
|
||||||
displayDensity.setOnPreferenceChangeListener(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean allowAllRotations(Context context) {
|
private static boolean allowAllRotations(Context context) {
|
||||||
|
@@ -32,6 +32,7 @@ public abstract class InstrumentedFragment extends PreferenceFragment {
|
|||||||
public static final int SOUND = UNDECLARED + 2;
|
public static final int SOUND = UNDECLARED + 2;
|
||||||
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declare the view of this category.
|
* Declare the view of this category.
|
||||||
|
@@ -11,18 +11,17 @@
|
|||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.settings;
|
package com.android.settings.display;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.support.annotation.ArrayRes;
|
|
||||||
import android.support.v7.preference.ListPreference;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.MathUtils;
|
import android.util.MathUtils;
|
||||||
@@ -30,16 +29,13 @@ import android.view.Display;
|
|||||||
import android.view.IWindowManager;
|
import android.view.IWindowManager;
|
||||||
import android.view.WindowManagerGlobal;
|
import android.view.WindowManagerGlobal;
|
||||||
|
|
||||||
import com.android.settings.R;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Preference for changing the density of the display on which the preference
|
* Utility methods for working with display density.
|
||||||
* is visible.
|
|
||||||
*/
|
*/
|
||||||
public class DisplayDensityPreference extends ListPreference {
|
class DisplayDensityUtils {
|
||||||
private static final String LOG_TAG = "DisplayDensityPreference";
|
private static final String LOG_TAG = "DisplayDensityUtils";
|
||||||
|
|
||||||
/** Minimum increment between density scales. */
|
/** Minimum increment between density scales. */
|
||||||
private static final float MIN_SCALE_INTERVAL = 0.09f;
|
private static final float MIN_SCALE_INTERVAL = 0.09f;
|
||||||
@@ -50,28 +46,28 @@ public class DisplayDensityPreference extends ListPreference {
|
|||||||
/** Maximum density scale. The actual scale used depends on the device. */
|
/** Maximum density scale. The actual scale used depends on the device. */
|
||||||
private static final float MAX_SCALE = 1.50f;
|
private static final float MAX_SCALE = 1.50f;
|
||||||
|
|
||||||
/** Sentinel value for "normal" scaling (effectively disabled). */
|
|
||||||
private static final int DENSITY_VALUE_NORMAL = -1;
|
|
||||||
|
|
||||||
/** Summary used for "normal" scale. */
|
/** Summary used for "normal" scale. */
|
||||||
private static final int DENSITY_SUMMARY_NORMAL = R.string.force_density_summary_normal;
|
private static final int SUMMARY_NORMAL = R.string.screen_zoom_summary_normal;
|
||||||
|
|
||||||
|
/** Summary used for "custom" scale. */
|
||||||
|
private static final int SUMMARY_CUSTOM = R.string.screen_zoom_summary_custom;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Summaries for scales smaller than "normal" in order of smallest to
|
* Summaries for scales smaller than "normal" in order of smallest to
|
||||||
* largest.
|
* largest.
|
||||||
*/
|
*/
|
||||||
private static final int[] SMALLER_SUMMARIES = new int[] {
|
private static final int[] SUMMARIES_SMALLER = new int[] {
|
||||||
R.string.force_density_summary_small
|
R.string.screen_zoom_summary_small
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Summaries for scales larger than "normal" in order of smallest to
|
* Summaries for scales larger than "normal" in order of smallest to
|
||||||
* largest.
|
* largest.
|
||||||
*/
|
*/
|
||||||
private static final int[] LARGER_SUMMARIES = new int[] {
|
private static final int[] SUMMARIES_LARGER = new int[] {
|
||||||
R.string.force_density_summary_large,
|
R.string.screen_zoom_summary_large,
|
||||||
R.string.force_density_summary_very_large,
|
R.string.screen_zoom_summary_very_large,
|
||||||
R.string.force_density_summary_extremely_large,
|
R.string.screen_zoom_summary_extremely_large,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -81,24 +77,24 @@ public class DisplayDensityPreference extends ListPreference {
|
|||||||
*/
|
*/
|
||||||
private static final int MIN_DIMENSION_DP = 320;
|
private static final int MIN_DIMENSION_DP = 320;
|
||||||
|
|
||||||
/** The ID of the display affected by this preference. */
|
private final String[] mEntries;
|
||||||
private int mDisplayId = Display.DEFAULT_DISPLAY;
|
private final int[] mValues;
|
||||||
|
|
||||||
public DisplayDensityPreference(Context context, AttributeSet attrs) {
|
private final int mNormalDensity;
|
||||||
super(context, attrs);
|
private final int mCurrentIndex;
|
||||||
|
|
||||||
if (!prepareList()) {
|
public DisplayDensityUtils(Context context) {
|
||||||
setEnabled(false);
|
final int normalDensity = DisplayDensityUtils.getNormalDisplayDensity(
|
||||||
}
|
Display.DEFAULT_DISPLAY);
|
||||||
|
if (normalDensity <= 0) {
|
||||||
|
mEntries = null;
|
||||||
|
mValues = null;
|
||||||
|
mNormalDensity = 0;
|
||||||
|
mCurrentIndex = -1;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean prepareList() {
|
final Resources res = context.getResources();
|
||||||
final int initialDensity = getInitialDisplayDensity(mDisplayId);
|
|
||||||
if (initialDensity <= 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Resources res = getContext().getResources();
|
|
||||||
final DisplayMetrics metrics = res.getDisplayMetrics();
|
final DisplayMetrics metrics = res.getDisplayMetrics();
|
||||||
final int currentDensity = metrics.densityDpi;
|
final int currentDensity = metrics.densityDpi;
|
||||||
int currentDensityIndex = -1;
|
int currentDensityIndex = -1;
|
||||||
@@ -106,46 +102,46 @@ public class DisplayDensityPreference extends ListPreference {
|
|||||||
// Compute number of "larger" and "smaller" scales for this display.
|
// Compute number of "larger" and "smaller" scales for this display.
|
||||||
final int minDimensionPx = Math.min(metrics.widthPixels, metrics.heightPixels);
|
final int minDimensionPx = Math.min(metrics.widthPixels, metrics.heightPixels);
|
||||||
final int maxDensity = DisplayMetrics.DENSITY_MEDIUM * minDimensionPx / MIN_DIMENSION_DP;
|
final int maxDensity = DisplayMetrics.DENSITY_MEDIUM * minDimensionPx / MIN_DIMENSION_DP;
|
||||||
final float maxScale = Math.min(MAX_SCALE, maxDensity / (float) initialDensity);
|
final float maxScale = Math.min(MAX_SCALE, maxDensity / (float) normalDensity);
|
||||||
final float minScale = MIN_SCALE;
|
final float minScale = MIN_SCALE;
|
||||||
final int numLarger = (int) MathUtils.constrain((maxScale - 1) / MIN_SCALE_INTERVAL,
|
final int numLarger = (int) MathUtils.constrain((maxScale - 1) / MIN_SCALE_INTERVAL,
|
||||||
0, LARGER_SUMMARIES.length);
|
0, SUMMARIES_LARGER.length);
|
||||||
final int numSmaller = (int) MathUtils.constrain((1 - minScale) / MIN_SCALE_INTERVAL,
|
final int numSmaller = (int) MathUtils.constrain((1 - minScale) / MIN_SCALE_INTERVAL,
|
||||||
0, SMALLER_SUMMARIES.length);
|
0, SUMMARIES_SMALLER.length);
|
||||||
|
|
||||||
CharSequence[] values = new CharSequence[1 + numSmaller + numLarger];
|
String[] entries = new String[1 + numSmaller + numLarger];
|
||||||
CharSequence[] entries = new CharSequence[values.length];
|
int[] values = new int[entries.length];
|
||||||
int curIndex = 0;
|
int curIndex = 0;
|
||||||
|
|
||||||
if (numSmaller > 0) {
|
if (numSmaller > 0) {
|
||||||
final float interval = (1 - minScale) / numSmaller;
|
final float interval = (1 - minScale) / numSmaller;
|
||||||
for (int i = numSmaller - 1; i >= 0; i--) {
|
for (int i = numSmaller - 1; i >= 0; i--) {
|
||||||
final int density = (int) (initialDensity * (1 - (i + 1) * interval));
|
final int density = (int) (normalDensity * (1 - (i + 1) * interval));
|
||||||
if (currentDensity == density) {
|
if (currentDensity == density) {
|
||||||
currentDensityIndex = curIndex;
|
currentDensityIndex = curIndex;
|
||||||
}
|
}
|
||||||
values[curIndex] = Integer.toString(density);
|
entries[curIndex] = res.getString(SUMMARIES_SMALLER[i]);
|
||||||
entries[curIndex] = res.getText(SMALLER_SUMMARIES[i]);
|
values[curIndex] = density;
|
||||||
curIndex++;
|
curIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentDensity == initialDensity) {
|
if (currentDensity == normalDensity) {
|
||||||
currentDensityIndex = curIndex;
|
currentDensityIndex = curIndex;
|
||||||
}
|
}
|
||||||
values[curIndex] = Integer.toString(DENSITY_VALUE_NORMAL);
|
values[curIndex] = normalDensity;
|
||||||
entries[curIndex] = res.getText(DENSITY_SUMMARY_NORMAL);
|
entries[curIndex] = res.getString(SUMMARY_NORMAL);
|
||||||
curIndex++;
|
curIndex++;
|
||||||
|
|
||||||
if (numLarger > 0) {
|
if (numLarger > 0) {
|
||||||
final float interval = (maxScale - 1) / numLarger;
|
final float interval = (maxScale - 1) / numLarger;
|
||||||
for (int i = 0; i < numLarger; i++) {
|
for (int i = 0; i < numLarger; i++) {
|
||||||
final int density = (int) (initialDensity * (1 + (i + 1) * interval));
|
final int density = (int) (normalDensity * (1 + (i + 1) * interval));
|
||||||
if (currentDensity == density) {
|
if (currentDensity == density) {
|
||||||
currentDensityIndex = curIndex;
|
currentDensityIndex = curIndex;
|
||||||
}
|
}
|
||||||
values[curIndex] = Integer.toString(density);
|
values[curIndex] = density;
|
||||||
entries[curIndex] = res.getText(LARGER_SUMMARIES[i]);
|
entries[curIndex] = res.getString(SUMMARIES_LARGER[i]);
|
||||||
curIndex++;
|
curIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -157,63 +153,46 @@ public class DisplayDensityPreference extends ListPreference {
|
|||||||
// We don't understand the current density. Must have been set by
|
// We don't understand the current density. Must have been set by
|
||||||
// someone else. Make room for another entry...
|
// someone else. Make room for another entry...
|
||||||
values = Arrays.copyOf(values, values.length + 1);
|
values = Arrays.copyOf(values, values.length + 1);
|
||||||
values[curIndex] = res.getString(R.string.force_density_summary_custom, currentDensity);
|
values[curIndex] = currentDensity;
|
||||||
|
|
||||||
entries = Arrays.copyOf(entries, values.length + 1);
|
entries = Arrays.copyOf(entries, values.length + 1);
|
||||||
entries[curIndex] = Integer.toString(currentDensity);
|
entries[curIndex] = res.getString(SUMMARY_CUSTOM, currentDensity);
|
||||||
|
|
||||||
displayIndex = curIndex;
|
displayIndex = curIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
super.setEntryValues(values);
|
mNormalDensity = normalDensity;
|
||||||
super.setEntries(entries);
|
mCurrentIndex = displayIndex;
|
||||||
|
mEntries = entries;
|
||||||
setValueIndex(displayIndex);
|
mValues = values;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public String[] getEntries() {
|
||||||
public boolean callChangeListener(Object newValue) {
|
return mEntries;
|
||||||
final boolean allowed = super.callChangeListener(newValue);
|
|
||||||
if (allowed) {
|
|
||||||
final int density = Integer.parseInt((String) newValue);
|
|
||||||
setForcedDisplayDensity(mDisplayId, density);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return allowed;
|
public int[] getValues() {
|
||||||
|
return mValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public int getCurrentIndex() {
|
||||||
public void setEntries(CharSequence[] entries) {
|
return mCurrentIndex;
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public int getNormalDensity() {
|
||||||
public void setEntries(@ArrayRes int entriesResId) {
|
return mNormalDensity;
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setEntryValues(CharSequence[] entryValues) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setEntryValues(@ArrayRes int entryValuesResId) {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the initial density for the specified display.
|
* Returns the normal (default) density for the specified display.
|
||||||
*
|
*
|
||||||
* @param displayId the identifier of the display
|
* @param displayId the identifier of the display
|
||||||
* @return the initial density of the specified display, or {@code -1} if
|
* @return the normal density of the specified display, or {@code -1} if
|
||||||
* the display does not exist or the density could not be obtained
|
* the display does not exist or the density could not be obtained
|
||||||
*/
|
*/
|
||||||
private static int getInitialDisplayDensity(int displayId) {
|
private static int getNormalDisplayDensity(int displayId) {
|
||||||
try {
|
try {
|
||||||
IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
|
final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
|
||||||
return wm.getInitialDisplayDensity(displayId);
|
return wm.getInitialDisplayDensity(displayId);
|
||||||
} catch (RemoteException exc) {
|
} catch (RemoteException exc) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -224,20 +203,34 @@ public class DisplayDensityPreference extends ListPreference {
|
|||||||
* Asynchronously applies display density changes to the specified display.
|
* Asynchronously applies display density changes to the specified display.
|
||||||
*
|
*
|
||||||
* @param displayId the identifier of the display to modify
|
* @param displayId the identifier of the display to modify
|
||||||
* @param density the density to force for the specified display, or <= 0
|
|
||||||
* to clear any previously forced density
|
|
||||||
*/
|
*/
|
||||||
private static void setForcedDisplayDensity(final int displayId, final int density) {
|
public static void clearForcedDisplayDensity(final int displayId) {
|
||||||
AsyncTask.execute(new Runnable() {
|
AsyncTask.execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
|
final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
|
||||||
if (density <= 0) {
|
|
||||||
wm.clearForcedDisplayDensity(displayId);
|
wm.clearForcedDisplayDensity(displayId);
|
||||||
} else {
|
} catch (RemoteException exc) {
|
||||||
wm.setForcedDisplayDensity(displayId, density);
|
Log.w(LOG_TAG, "Unable to clear forced display density setting");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asynchronously applies display density changes to the specified display.
|
||||||
|
*
|
||||||
|
* @param displayId the identifier of the display to modify
|
||||||
|
* @param density the density to force for the specified display
|
||||||
|
*/
|
||||||
|
public static void setForcedDisplayDensity(final int displayId, final int density) {
|
||||||
|
AsyncTask.execute(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
|
||||||
|
wm.setForcedDisplayDensity(displayId, density);
|
||||||
} catch (RemoteException exc) {
|
} catch (RemoteException exc) {
|
||||||
Log.w(LOG_TAG, "Unable to save forced display density setting");
|
Log.w(LOG_TAG, "Unable to save forced display density setting");
|
||||||
}
|
}
|
53
src/com/android/settings/display/ScreenZoomPreference.java
Normal file
53
src/com/android/settings/display/ScreenZoomPreference.java
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* 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.display;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.support.v4.content.res.TypedArrayUtils;
|
||||||
|
import android.support.v7.preference.PreferenceGroup;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preference for changing the density of the display on which the preference
|
||||||
|
* is visible.
|
||||||
|
*/
|
||||||
|
public class ScreenZoomPreference extends PreferenceGroup {
|
||||||
|
public ScreenZoomPreference(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs, TypedArrayUtils.getAttr(context,
|
||||||
|
android.support.v7.preference.R.attr.preferenceScreenStyle,
|
||||||
|
android.R.attr.preferenceScreenStyle));
|
||||||
|
|
||||||
|
setFragment("com.android.settings.display.ScreenZoomSettings");
|
||||||
|
|
||||||
|
final DisplayDensityUtils density = new DisplayDensityUtils(context);
|
||||||
|
final int defaultIndex = density.getCurrentIndex();
|
||||||
|
if (defaultIndex < 0) {
|
||||||
|
setVisible(false);
|
||||||
|
setEnabled(false);
|
||||||
|
} else {
|
||||||
|
final String[] entries = density.getEntries();
|
||||||
|
final int currentIndex = density.getCurrentIndex();
|
||||||
|
setSummary(entries[currentIndex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isOnSameScreenAsChildren() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
272
src/com/android/settings/display/ScreenZoomSettings.java
Normal file
272
src/com/android/settings/display/ScreenZoomSettings.java
Normal file
@@ -0,0 +1,272 @@
|
|||||||
|
/*
|
||||||
|
* 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.display;
|
||||||
|
|
||||||
|
import com.android.settings.InstrumentedFragment;
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.SettingsPreferenceFragment;
|
||||||
|
import com.android.settings.search.BaseSearchIndexProvider;
|
||||||
|
import com.android.settings.search.Indexable;
|
||||||
|
import com.android.settings.search.SearchIndexableRaw;
|
||||||
|
|
||||||
|
import android.annotation.Nullable;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.os.Bundle;
|
||||||
|
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.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preference fragment used to control screen zoom.
|
||||||
|
*/
|
||||||
|
public class ScreenZoomSettings extends SettingsPreferenceFragment 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 mInitialIndex;
|
||||||
|
|
||||||
|
private int mCurrentIndex;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
final DisplayDensityUtils density = new DisplayDensityUtils(getContext());
|
||||||
|
|
||||||
|
final int initialIndex = density.getCurrentIndex();
|
||||||
|
if (initialIndex < 0) {
|
||||||
|
// Failed to obtain normal density, which means we failed to
|
||||||
|
// connect to the window manager service. Just use the current
|
||||||
|
// density and don't let the user change anything.
|
||||||
|
final int densityDpi = getResources().getDisplayMetrics().densityDpi;
|
||||||
|
mValues = new int[] { densityDpi };
|
||||||
|
mEntries = new String[] { getString(R.string.screen_zoom_summary_normal) };
|
||||||
|
mInitialIndex = 0;
|
||||||
|
mNormalDensity = densityDpi;
|
||||||
|
} else {
|
||||||
|
mValues = density.getValues();
|
||||||
|
mEntries = density.getEntries();
|
||||||
|
mInitialIndex = initialIndex;
|
||||||
|
mNormalDensity = density.getNormalDensity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
|
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.
|
||||||
|
final Context context = getContext();
|
||||||
|
final Configuration origConfig = context.getResources().getConfiguration();
|
||||||
|
for (int mValue : mValues) {
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
private void commit() {
|
||||||
|
final int densityDpi = mValues[mCurrentIndex];
|
||||||
|
if (densityDpi == mNormalDensity) {
|
||||||
|
DisplayDensityUtils.clearForcedDisplayDensity(Display.DEFAULT_DISPLAY);
|
||||||
|
} else {
|
||||||
|
DisplayDensityUtils.setForcedDisplayDensity(Display.DEFAULT_DISPLAY, densityDpi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getMetricsCategory() {
|
||||||
|
return InstrumentedFragment.DISPLAY_SCREEN_ZOOM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Index provider used to expose this fragment in search. */
|
||||||
|
public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||||
|
new BaseSearchIndexProvider() {
|
||||||
|
@Override
|
||||||
|
public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
|
||||||
|
final Resources res = context.getResources();
|
||||||
|
final SearchIndexableRaw data = new SearchIndexableRaw(context);
|
||||||
|
data.title = res.getString(R.string.screen_zoom_title);
|
||||||
|
data.screenTitle = res.getString(R.string.screen_zoom_title);
|
||||||
|
data.keywords = res.getString(R.string.screen_zoom_keywords);
|
||||||
|
|
||||||
|
final List<SearchIndexableRaw> result = new ArrayList<>(1);
|
||||||
|
result.add(data);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* 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.display;
|
||||||
|
|
||||||
|
import android.annotation.Nullable;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension of FrameLayout that consumes all touch events.
|
||||||
|
*/
|
||||||
|
public class TouchBlockingFrameLayout extends FrameLayout {
|
||||||
|
public TouchBlockingFrameLayout(Context context, @Nullable AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@@ -36,6 +36,7 @@ import com.android.settings.applications.AdvancedAppSettings;
|
|||||||
import com.android.settings.applications.ManageDefaultApps;
|
import com.android.settings.applications.ManageDefaultApps;
|
||||||
import com.android.settings.bluetooth.BluetoothSettings;
|
import com.android.settings.bluetooth.BluetoothSettings;
|
||||||
import com.android.settings.deviceinfo.StorageSettings;
|
import com.android.settings.deviceinfo.StorageSettings;
|
||||||
|
import com.android.settings.display.ScreenZoomSettings;
|
||||||
import com.android.settings.fuelgauge.BatterySaverSettings;
|
import com.android.settings.fuelgauge.BatterySaverSettings;
|
||||||
import com.android.settings.fuelgauge.PowerUsageSummary;
|
import com.android.settings.fuelgauge.PowerUsageSummary;
|
||||||
import com.android.settings.inputmethod.InputMethodAndLanguageSettings;
|
import com.android.settings.inputmethod.InputMethodAndLanguageSettings;
|
||||||
@@ -122,6 +123,7 @@ public final class Ranking {
|
|||||||
|
|
||||||
// Display
|
// Display
|
||||||
sRankMap.put(DisplaySettings.class.getName(), RANK_DISPLAY);
|
sRankMap.put(DisplaySettings.class.getName(), RANK_DISPLAY);
|
||||||
|
sRankMap.put(ScreenZoomSettings.class.getName(), RANK_WIFI);
|
||||||
|
|
||||||
// Wallpapers
|
// Wallpapers
|
||||||
sRankMap.put(WallpaperTypeSettings.class.getName(), RANK_WALLPAPER);
|
sRankMap.put(WallpaperTypeSettings.class.getName(), RANK_WALLPAPER);
|
||||||
|
@@ -38,6 +38,7 @@ import com.android.settings.applications.AdvancedAppSettings;
|
|||||||
import com.android.settings.applications.ManageDefaultApps;
|
import com.android.settings.applications.ManageDefaultApps;
|
||||||
import com.android.settings.bluetooth.BluetoothSettings;
|
import com.android.settings.bluetooth.BluetoothSettings;
|
||||||
import com.android.settings.deviceinfo.StorageSettings;
|
import com.android.settings.deviceinfo.StorageSettings;
|
||||||
|
import com.android.settings.display.ScreenZoomSettings;
|
||||||
import com.android.settings.fuelgauge.BatterySaverSettings;
|
import com.android.settings.fuelgauge.BatterySaverSettings;
|
||||||
import com.android.settings.fuelgauge.PowerUsageSummary;
|
import com.android.settings.fuelgauge.PowerUsageSummary;
|
||||||
import com.android.settings.inputmethod.InputMethodAndLanguageSettings;
|
import com.android.settings.inputmethod.InputMethodAndLanguageSettings;
|
||||||
@@ -131,6 +132,13 @@ public final class SearchIndexableResources {
|
|||||||
HomeSettings.class.getName(),
|
HomeSettings.class.getName(),
|
||||||
R.drawable.ic_settings_home));
|
R.drawable.ic_settings_home));
|
||||||
|
|
||||||
|
sResMap.put(ScreenZoomSettings.class.getName(),
|
||||||
|
new SearchIndexableResource(
|
||||||
|
Ranking.getRankForClassName(ScreenZoomSettings.class.getName()),
|
||||||
|
NO_DATA_RES_ID,
|
||||||
|
ScreenZoomSettings.class.getName(),
|
||||||
|
R.drawable.ic_settings_display));
|
||||||
|
|
||||||
sResMap.put(DisplaySettings.class.getName(),
|
sResMap.put(DisplaySettings.class.getName(),
|
||||||
new SearchIndexableResource(
|
new SearchIndexableResource(
|
||||||
Ranking.getRankForClassName(DisplaySettings.class.getName()),
|
Ranking.getRankForClassName(DisplaySettings.class.getName()),
|
||||||
|
Reference in New Issue
Block a user