diff options
| author | 2013-03-09 00:09:18 +0000 | |
|---|---|---|
| committer | 2013-03-09 00:09:18 +0000 | |
| commit | 6e5d6492db4f0bed604e67ee53b0c99e0685c55f (patch) | |
| tree | 5663875e747699409035d29bf3c9f7e3ebd1a88e | |
| parent | 515b51f83f1363329c66372be51813db15fb21c6 (diff) | |
| parent | 0caa377f4688f175ae22229a10294468610a116e (diff) | |
Merge "Fix long-standing bug with LockPatternView drawing artifacts" into jb-mr2-dev
| -rw-r--r-- | core/java/com/android/internal/widget/LockPatternView.java | 152 |
1 files changed, 47 insertions, 105 deletions
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java index 7a76ab01b8c0..1b088b3c81ac 100644 --- a/core/java/com/android/internal/widget/LockPatternView.java +++ b/core/java/com/android/internal/widget/LockPatternView.java @@ -38,6 +38,7 @@ import android.view.View; import android.view.accessibility.AccessibilityManager; import com.android.internal.R; +import com.android.internal.widget.LockPatternView.Cell; import java.util.ArrayList; import java.util.List; @@ -72,6 +73,12 @@ public class LockPatternView extends View { */ private static final int MILLIS_PER_CIRCLE_ANIMATING = 700; + /** + * This can be used to avoid updating the display for very small motions or noisy panels. + * It didn't seem to have much impact on the devices tested, so currently set to 0. + */ + private static final float DRAG_THRESHHOLD = 0.0f; + private OnPatternListener mOnPatternListener; private ArrayList<Cell> mPattern = new ArrayList<Cell>(9); @@ -674,10 +681,11 @@ public class LockPatternView extends View { // Handle all recent motion events so we don't skip any cells even when the device // is busy... final int historySize = event.getHistorySize(); + Rect invalidateRect = mInvalidate; + boolean invalidateNow = false; for (int i = 0; i < historySize + 1; i++) { final float x = i < historySize ? event.getHistoricalX(i) : event.getX(); final float y = i < historySize ? event.getHistoricalY(i) : event.getY(); - final int patternSizePreHitDetect = mPattern.size(); Cell hitCell = detectAndAddHit(x, y); final int patternSize = mPattern.size(); if (hitCell != null && patternSize == 1) { @@ -687,114 +695,48 @@ public class LockPatternView extends View { // note current x and y for rubber banding of in progress patterns final float dx = Math.abs(x - mInProgressX); final float dy = Math.abs(y - mInProgressY); - if (dx + dy > mSquareWidth * 0.01f) { - float oldX = mInProgressX; - float oldY = mInProgressY; - - mInProgressX = x; - mInProgressY = y; - - if (mPatternInProgress && patternSize > 0) { - final ArrayList<Cell> pattern = mPattern; - final float radius = mSquareWidth * mDiameterFactor * 0.5f; - - final Cell lastCell = pattern.get(patternSize - 1); - - float startX = getCenterXForColumn(lastCell.column); - float startY = getCenterYForRow(lastCell.row); - - float left; - float top; - float right; - float bottom; - - final Rect invalidateRect = mInvalidate; - - if (startX < x) { - left = startX; - right = x; - } else { - left = x; - right = startX; - } - - if (startY < y) { - top = startY; - bottom = y; - } else { - top = y; - bottom = startY; - } - - // Invalidate between the pattern's last cell and the current location - invalidateRect.set((int) (left - radius), (int) (top - radius), - (int) (right + radius), (int) (bottom + radius)); - - if (startX < oldX) { - left = startX; - right = oldX; - } else { - left = oldX; - right = startX; - } - - if (startY < oldY) { - top = startY; - bottom = oldY; - } else { - top = oldY; - bottom = startY; - } - - // Invalidate between the pattern's last cell and the previous location - invalidateRect.union((int) (left - radius), (int) (top - radius), - (int) (right + radius), (int) (bottom + radius)); - - // Invalidate between the pattern's new cell and the pattern's previous cell - if (hitCell != null) { - startX = getCenterXForColumn(hitCell.column); - startY = getCenterYForRow(hitCell.row); - - if (patternSize >= 2) { - // (re-using hitcell for old cell) - hitCell = pattern.get(patternSize - 1 - (patternSize - patternSizePreHitDetect)); - oldX = getCenterXForColumn(hitCell.column); - oldY = getCenterYForRow(hitCell.row); - - if (startX < oldX) { - left = startX; - right = oldX; - } else { - left = oldX; - right = startX; - } - - if (startY < oldY) { - top = startY; - bottom = oldY; - } else { - top = oldY; - bottom = startY; - } - } else { - left = right = startX; - top = bottom = startY; - } - - final float widthOffset = mSquareWidth / 2f; - final float heightOffset = mSquareHeight / 2f; - - invalidateRect.set((int) (left - widthOffset), - (int) (top - heightOffset), (int) (right + widthOffset), - (int) (bottom + heightOffset)); - } + if (dx > DRAG_THRESHHOLD || dy > DRAG_THRESHHOLD) { + invalidateNow = true; + } - invalidate(invalidateRect); - } else { - invalidate(); + if (mPatternInProgress && patternSize > 0) { + final ArrayList<Cell> pattern = mPattern; + final Cell lastCell = pattern.get(patternSize - 1); + float startX = getCenterXForColumn(lastCell.column); + float startY = getCenterYForRow(lastCell.row); + + // Adjust for current position. Radius accounts for line width. + final float radius = (mSquareWidth * mDiameterFactor * 0.5f); + float left = Math.min(startX, x) - radius; + float right = Math.max(startX, x) + radius; + float top = Math.min(startY, y) - radius; + float bottom = Math.max(startY, y) + radius; + + // Invalidate between the pattern's new cell and the pattern's previous cell + if (hitCell != null && patternSize >= 2) { + final float width = mSquareWidth * 0.5f; + final float height = mSquareHeight * 0.5f; + final float x2 = getCenterXForColumn(hitCell.column); + final float y2 = getCenterYForRow(hitCell.row); + left = Math.min(x2, left - width); + right = Math.max(x2, right + width); + top = Math.min(y2, top - height); + bottom = Math.max(y2, bottom + height); } + + // Invalidate between the pattern's last cell and the previous location + invalidateRect.union(Math.round(left), Math.round(top), + Math.round(right), Math.round(bottom)); } } + mInProgressX = event.getX(); + mInProgressY = event.getY(); + + // To save updates, we only invalidate if the user moved beyond a certain amount. + if (invalidateNow) { + invalidate(invalidateRect); + invalidateRect.setEmpty(); + } } private void sendAccessEvent(int resId) { |