widget: Adding support for custom LockPatternView.
OEMs can overlay the default 9 dots by providing two drawables that represent those dots: * lockscreen_notselected: asset to display when a cell has not been selected. * lockscreen_selected: asset to display when a cell has been selected. BUG: 33755663 Change-Id: Ic595b01f5e1321696b7a3feb0ff73c1acccfb942
This commit is contained in:
@@ -24,6 +24,7 @@ import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.CanvasProperty;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.Rect;
|
||||
@@ -143,6 +144,10 @@ public class LockPatternView extends View {
|
||||
private PatternExploreByTouchHelper mExploreByTouchHelper;
|
||||
private AudioManager mAudioManager;
|
||||
|
||||
private Drawable mSelectedDrawable;
|
||||
private Drawable mNotSelectedDrawable;
|
||||
private boolean mUseLockPatternDrawable;
|
||||
|
||||
/**
|
||||
* Represents a cell in the 3 X 3 matrix of the unlock pattern view.
|
||||
*/
|
||||
@@ -314,6 +319,12 @@ public class LockPatternView extends View {
|
||||
mDotSizeActivated = getResources().getDimensionPixelSize(
|
||||
R.dimen.lock_pattern_dot_size_activated);
|
||||
|
||||
mUseLockPatternDrawable = getResources().getBoolean(R.bool.use_lock_pattern_drawable);
|
||||
if (mUseLockPatternDrawable) {
|
||||
mSelectedDrawable = getResources().getDrawable(R.drawable.lockscreen_selected);
|
||||
mNotSelectedDrawable = getResources().getDrawable(R.drawable.lockscreen_notselected);
|
||||
}
|
||||
|
||||
mPaint.setAntiAlias(true);
|
||||
mPaint.setDither(true);
|
||||
|
||||
@@ -621,6 +632,11 @@ public class LockPatternView extends View {
|
||||
final int height = h - mPaddingTop - mPaddingBottom;
|
||||
mSquareHeight = height / 3.0f;
|
||||
mExploreByTouchHelper.invalidateRoot();
|
||||
|
||||
if (mUseLockPatternDrawable) {
|
||||
mNotSelectedDrawable.setBounds(mPaddingLeft, mPaddingTop, width, height);
|
||||
mSelectedDrawable.setBounds(mPaddingLeft, mPaddingTop, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
private int resolveMeasured(int measureSpec, int desired)
|
||||
@@ -1095,14 +1111,18 @@ public class LockPatternView extends View {
|
||||
CellState cellState = mCellStates[i][j];
|
||||
float centerX = getCenterXForColumn(j);
|
||||
float translationY = cellState.translationY;
|
||||
if (isHardwareAccelerated() && cellState.hwAnimating) {
|
||||
DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas;
|
||||
displayListCanvas.drawCircle(cellState.hwCenterX, cellState.hwCenterY,
|
||||
cellState.hwRadius, cellState.hwPaint);
|
||||
} else {
|
||||
drawCircle(canvas, (int) centerX, (int) centerY + translationY,
|
||||
cellState.radius, drawLookup[i][j], cellState.alpha);
|
||||
|
||||
if (mUseLockPatternDrawable) {
|
||||
drawCellDrawable(canvas, i, j, cellState.radius, drawLookup[i][j]);
|
||||
} else {
|
||||
if (isHardwareAccelerated() && cellState.hwAnimating) {
|
||||
DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas;
|
||||
displayListCanvas.drawCircle(cellState.hwCenterX, cellState.hwCenterY,
|
||||
cellState.hwRadius, cellState.hwPaint);
|
||||
} else {
|
||||
drawCircle(canvas, (int) centerX, (int) centerY + translationY,
|
||||
cellState.radius, drawLookup[i][j], cellState.alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1193,6 +1213,30 @@ public class LockPatternView extends View {
|
||||
canvas.drawCircle(centerX, centerY, radius, mPaint);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param partOfPattern Whether this circle is part of the pattern.
|
||||
*/
|
||||
private void drawCellDrawable(Canvas canvas, int i, int j, float radius,
|
||||
boolean partOfPattern) {
|
||||
Rect dst = new Rect(
|
||||
(int) (mPaddingLeft + j * mSquareWidth),
|
||||
(int) (mPaddingTop + i * mSquareHeight),
|
||||
(int) (mPaddingLeft + (j + 1) * mSquareWidth),
|
||||
(int) (mPaddingTop + (i + 1) * mSquareHeight));
|
||||
float scale = radius / (mDotSize / 2);
|
||||
|
||||
// Only draw on this square with the appropriate scale.
|
||||
canvas.save();
|
||||
canvas.clipRect(dst);
|
||||
canvas.scale(scale, scale, dst.centerX(), dst.centerY());
|
||||
if (!partOfPattern || scale > 1) {
|
||||
mNotSelectedDrawable.draw(canvas);
|
||||
} else {
|
||||
mSelectedDrawable.draw(canvas);
|
||||
}
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Parcelable onSaveInstanceState() {
|
||||
Parcelable superState = super.onSaveInstanceState();
|
||||
|
||||
50
core/res/res/drawable/lockscreen_notselected.xml
Normal file
50
core/res/res/drawable/lockscreen_notselected.xml
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="260dp"
|
||||
android:height="260dp"
|
||||
android:viewportWidth="260"
|
||||
android:viewportHeight="260">
|
||||
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M 43.3333 34.3333 C 48.3038627485 34.3333 52.3333 38.3627372515 52.3333 43.3333 C 52.3333 48.3038627485 48.3038627485 52.3333 43.3333 52.3333 C 38.3627372515 52.3333 34.3333 48.3038627485 34.3333 43.3333 C 34.3333 38.3627372515 38.3627372515 34.3333 43.3333 34.3333 Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M 43.3333 121 C 48.3038627485 121 52.3333 125.029437252 52.3333 130 C 52.3333 134.970562748 48.3038627485 139 43.3333 139 C 38.3627372515 139 34.3333 134.970562748 34.3333 130 C 34.3333 125.029437252 38.3627372515 121 43.3333 121 Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M 43.3333 207.6667 C 48.3038627485 207.6667 52.3333 211.696137252 52.3333 216.6667 C 52.3333 221.637262748 48.3038627485 225.6667 43.3333 225.6667 C 38.3627372515 225.6667 34.3333 221.637262748 34.3333 216.6667 C 34.3333 211.696137252 38.3627372515 207.6667 43.3333 207.6667 Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M 130 34.3333 C 134.970562748 34.3333 139 38.3627372515 139 43.3333 C 139 48.3038627485 134.970562748 52.3333 130 52.3333 C 125.029437252 52.3333 121 48.3038627485 121 43.3333 C 121 38.3627372515 125.029437252 34.3333 130 34.3333 Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M 130 121 C 134.970562748 121 139 125.029437252 139 130 C 139 134.970562748 134.970562748 139 130 139 C 125.029437252 139 121 134.970562748 121 130 C 121 125.029437252 125.029437252 121 130 121 Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M 130 207.6667 C 134.970562748 207.6667 139 211.696137252 139 216.6667 C 139 221.637262748 134.970562748 225.6667 130 225.6667 C 125.029437252 225.6667 121 221.637262748 121 216.6667 C 121 211.696137252 125.029437252 207.6667 130 207.6667 Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M 216.6667 34.3333 C 221.637262748 34.3333 225.6667 38.3627372515 225.6667 43.3333 C 225.6667 48.3038627485 221.637262748 52.3333 216.6667 52.3333 C 211.696137252 52.3333 207.6667 48.3038627485 207.6667 43.3333 C 207.6667 38.3627372515 211.696137252 34.3333 216.6667 34.3333 Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M 216.6667 121 C 221.637262748 121 225.6667 125.029437252 225.6667 130 C 225.6667 134.970562748 221.637262748 139 216.6667 139 C 211.696137252 139 207.6667 134.970562748 207.6667 130 C 207.6667 125.029437252 211.696137252 121 216.6667 121 Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M 216.6667 207.6667 C 221.637262748 207.6667 225.6667 211.696137252 225.6667 216.6667 C 225.6667 221.637262748 221.637262748 225.6667 216.6667 225.6667 C 211.696137252 225.6667 207.6667 221.637262748 207.6667 216.6667 C 207.6667 211.696137252 211.696137252 207.6667 216.6667 207.6667 Z" />
|
||||
</vector>
|
||||
50
core/res/res/drawable/lockscreen_selected.xml
Normal file
50
core/res/res/drawable/lockscreen_selected.xml
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="260dp"
|
||||
android:height="260dp"
|
||||
android:viewportWidth="260"
|
||||
android:viewportHeight="260">
|
||||
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M 43.3333 34.3333 C 48.3038627485 34.3333 52.3333 38.3627372515 52.3333 43.3333 C 52.3333 48.3038627485 48.3038627485 52.3333 43.3333 52.3333 C 38.3627372515 52.3333 34.3333 48.3038627485 34.3333 43.3333 C 34.3333 38.3627372515 38.3627372515 34.3333 43.3333 34.3333 Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M 43.3333 121 C 48.3038627485 121 52.3333 125.029437252 52.3333 130 C 52.3333 134.970562748 48.3038627485 139 43.3333 139 C 38.3627372515 139 34.3333 134.970562748 34.3333 130 C 34.3333 125.029437252 38.3627372515 121 43.3333 121 Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M 43.3333 207.6667 C 48.3038627485 207.6667 52.3333 211.696137252 52.3333 216.6667 C 52.3333 221.637262748 48.3038627485 225.6667 43.3333 225.6667 C 38.3627372515 225.6667 34.3333 221.637262748 34.3333 216.6667 C 34.3333 211.696137252 38.3627372515 207.6667 43.3333 207.6667 Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M 130 34.3333 C 134.970562748 34.3333 139 38.3627372515 139 43.3333 C 139 48.3038627485 134.970562748 52.3333 130 52.3333 C 125.029437252 52.3333 121 48.3038627485 121 43.3333 C 121 38.3627372515 125.029437252 34.3333 130 34.3333 Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M 130 121 C 134.970562748 121 139 125.029437252 139 130 C 139 134.970562748 134.970562748 139 130 139 C 125.029437252 139 121 134.970562748 121 130 C 121 125.029437252 125.029437252 121 130 121 Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M 130 207.6667 C 134.970562748 207.6667 139 211.696137252 139 216.6667 C 139 221.637262748 134.970562748 225.6667 130 225.6667 C 125.029437252 225.6667 121 221.637262748 121 216.6667 C 121 211.696137252 125.029437252 207.6667 130 207.6667 Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M 216.6667 34.3333 C 221.637262748 34.3333 225.6667 38.3627372515 225.6667 43.3333 C 225.6667 48.3038627485 221.637262748 52.3333 216.6667 52.3333 C 211.696137252 52.3333 207.6667 48.3038627485 207.6667 43.3333 C 207.6667 38.3627372515 211.696137252 34.3333 216.6667 34.3333 Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M 216.6667 121 C 221.637262748 121 225.6667 125.029437252 225.6667 130 C 225.6667 134.970562748 221.637262748 139 216.6667 139 C 211.696137252 139 207.6667 134.970562748 207.6667 130 C 207.6667 125.029437252 211.696137252 121 216.6667 121 Z" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M 216.6667 207.6667 C 221.637262748 207.6667 225.6667 211.696137252 225.6667 216.6667 C 225.6667 221.637262748 221.637262748 225.6667 216.6667 225.6667 C 211.696137252 225.6667 207.6667 221.637262748 207.6667 216.6667 C 207.6667 211.696137252 211.696137252 207.6667 216.6667 207.6667 Z" />
|
||||
</vector>
|
||||
@@ -24,4 +24,12 @@
|
||||
<bool name="show_ongoing_ime_switcher">true</bool>
|
||||
<bool name="action_bar_expanded_action_views_exclusive">true</bool>
|
||||
<bool name="target_honeycomb_needs_options_menu">true</bool>
|
||||
<!--
|
||||
Whether or not to use the drawable/lockscreen_notselected and
|
||||
drawable/lockscreen_selected instead of the generic dots when displaying
|
||||
the LockPatternView.
|
||||
The main purpose is for OEMs to customize the rendering of the
|
||||
lockscreen, setting this to true should come with customized drawables.
|
||||
-->
|
||||
<bool name="use_lock_pattern_drawable">false</bool>
|
||||
</resources>
|
||||
|
||||
@@ -2731,7 +2731,9 @@
|
||||
<!-- Screen-size-dependent modes for picker dialogs. -->
|
||||
<java-symbol type="integer" name="time_picker_mode" />
|
||||
<java-symbol type="integer" name="date_picker_mode" />
|
||||
|
||||
<java-symbol type="bool" name="config_permissionReviewRequired" />
|
||||
|
||||
<java-symbol type="bool" name="use_lock_pattern_drawable" />
|
||||
<java-symbol type="drawable" name="lockscreen_notselected" />
|
||||
<java-symbol type="drawable" name="lockscreen_selected" />
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user