summaryrefslogtreecommitdiffstats
path: root/core/java/android/widget
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-02-20 07:38:31 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-02-20 07:38:31 -0800
commit15ab3eae2ec3d73b3e8aa60b33ae41445bf83f4b (patch)
treed03d027a7ed97af616904e02a7b420babf40d44f /core/java/android/widget
parent3001a035439d8134a7d70d796376d1dfbff3cdcd (diff)
downloadframeworks_base-15ab3eae2ec3d73b3e8aa60b33ae41445bf83f4b.zip
frameworks_base-15ab3eae2ec3d73b3e8aa60b33ae41445bf83f4b.tar.gz
frameworks_base-15ab3eae2ec3d73b3e8aa60b33ae41445bf83f4b.tar.bz2
auto import from //branches/cupcake/...@132569
Diffstat (limited to 'core/java/android/widget')
-rw-r--r--core/java/android/widget/Adapter.java2
-rw-r--r--core/java/android/widget/TextView.java16
-rw-r--r--core/java/android/widget/ZoomRing.java113
-rw-r--r--core/java/android/widget/ZoomRingController.java82
4 files changed, 150 insertions, 63 deletions
diff --git a/core/java/android/widget/Adapter.java b/core/java/android/widget/Adapter.java
index e952dd5..f2b3e2a 100644
--- a/core/java/android/widget/Adapter.java
+++ b/core/java/android/widget/Adapter.java
@@ -116,7 +116,7 @@ public interface Adapter {
* can be converted to the other in {@link #getView}. Note: Integers must be in the
* range 0 to {@link #getViewTypeCount} - 1. {@link #IGNORE_ITEM_VIEW_TYPE} can
* also be returned.
- * @see IGNORE_ITEM_VIEW_TYPE
+ * @see #IGNORE_ITEM_VIEW_TYPE
*/
int getItemViewType(int position);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index bdc54ff..c852be5 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -4132,8 +4132,20 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
removeParcelableSpans(content, start, end);
content.replace(start, end, text.text);
}
- Selection.setSelection((Spannable)getText(),
- text.selectionStart, text.selectionEnd);
+
+ // Now set the selection position... make sure it is in range, to
+ // avoid crashes. If this is a partial update, it is possible that
+ // the underlying text may have changed, causing us problems here.
+ // Also we just don't want to trust clients to do the right thing.
+ Spannable sp = (Spannable)getText();
+ final int N = sp.length();
+ int start = text.selectionStart;
+ if (start < 0) start = 0;
+ else if (start > N) start = N;
+ int end = text.selectionEnd;
+ if (end < 0) end = 0;
+ else if (end > N) end = N;
+ Selection.setSelection(sp, start, end);
}
/**
diff --git a/core/java/android/widget/ZoomRing.java b/core/java/android/widget/ZoomRing.java
index 22881b3..a29e1a0 100644
--- a/core/java/android/widget/ZoomRing.java
+++ b/core/java/android/widget/ZoomRing.java
@@ -84,6 +84,10 @@ public class ZoomRing extends View {
private Drawable mThumbPlusArrowDrawable;
/** Shown beneath the thumb if we can still zoom out. */
private Drawable mThumbMinusArrowDrawable;
+ private static final int THUMB_ARROW_PLUS = 1 << 0;
+ private static final int THUMB_ARROW_MINUS = 1 << 1;
+ /** Bitwise-OR of {@link #THUMB_ARROW_MINUS} and {@link #THUMB_ARROW_PLUS} */
+ private int mThumbArrowsToDraw;
private static final int THUMB_ARROWS_FADE_DURATION = 300;
private long mThumbArrowsFadeStartTime;
private int mThumbArrowsAlpha = 255;
@@ -166,7 +170,7 @@ public class ZoomRing extends View {
// TODO: add padding to drawable
setBackgroundResource(R.drawable.zoom_ring_track);
// TODO get from style
- setRingBounds(30, Integer.MAX_VALUE);
+ setRingBounds(43, Integer.MAX_VALUE);
mThumbHalfHeight = mThumbDrawable.getIntrinsicHeight() / 2;
mThumbHalfWidth = mThumbDrawable.getIntrinsicWidth() / 2;
@@ -276,7 +280,7 @@ public class ZoomRing extends View {
thumbCenterX + mThumbHalfWidth,
thumbCenterY + mThumbHalfHeight);
- if (mThumbArrowsAlpha > 0) {
+ if (mThumbArrowsToDraw > 0) {
setThumbArrowsAngle(angle);
}
@@ -420,12 +424,15 @@ public class ZoomRing extends View {
switch (action) {
case MotionEvent.ACTION_DOWN:
- mCallback.onUserInteractionStarted();
-
if (time - mPreviousUpTime <= DOUBLE_TAP_DISMISS_TIMEOUT) {
mCallback.onZoomRingDismissed(true);
+ onTouchUp(time);
+
+ // Dismissing, so halt here
+ return true;
}
+ mCallback.onUserInteractionStarted();
mPreviousDownX = x;
mPreviousDownY = y;
resetState();
@@ -441,23 +448,7 @@ public class ZoomRing extends View {
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
- if (mMode == MODE_MOVE_ZOOM_RING || mMode == MODE_WAITING_FOR_MOVE_ZOOM_RING) {
- mCallback.onZoomRingSetMovableHintVisible(false);
- if (mMode == MODE_MOVE_ZOOM_RING) {
- mCallback.onZoomRingMovingStopped();
- }
- } else if (mMode == MODE_DRAG_THUMB || mMode == MODE_TAP_DRAG ||
- mMode == MODE_WAITING_FOR_DRAG_THUMB) {
- onThumbDragStopped();
-
- if (mMode == MODE_DRAG_THUMB) {
- // Animate back to a tick
- setThumbAngleAnimated(mPreviousCallbackAngle, 0);
- }
- }
-
- mPreviousUpTime = time;
- mCallback.onUserInteractionStopped();
+ onTouchUp(time);
return true;
default:
@@ -524,10 +515,9 @@ public class ZoomRing extends View {
deltaThumbAndTick = getDelta(mThumbAngle, tickAngle, !oldDirectionIsCcw);
boundAngle = getBoundIfExceeds(mThumbAngle, deltaThumbAndTick);
if (boundAngle != Integer.MIN_VALUE) {
- Log
- .d(
- TAG,
- "Tapped somewhere where the shortest distance goes through a bound, but then the opposite direction also went through a bound!");
+ // Not allowed to be here, it is between two bounds
+ mMode = MODE_IGNORE_UNTIL_UP;
+ return true;
}
}
}
@@ -574,6 +564,26 @@ public class ZoomRing extends View {
return true;
}
+
+ private void onTouchUp(long time) {
+ if (mMode == MODE_MOVE_ZOOM_RING || mMode == MODE_WAITING_FOR_MOVE_ZOOM_RING) {
+ mCallback.onZoomRingSetMovableHintVisible(false);
+ if (mMode == MODE_MOVE_ZOOM_RING) {
+ mCallback.onZoomRingMovingStopped();
+ }
+ } else if (mMode == MODE_DRAG_THUMB || mMode == MODE_TAP_DRAG ||
+ mMode == MODE_WAITING_FOR_DRAG_THUMB) {
+ onThumbDragStopped();
+
+ if (mMode == MODE_DRAG_THUMB) {
+ // Animate back to a tick
+ setThumbAngleAnimated(mPreviousCallbackAngle, 0);
+ }
+ }
+
+ mPreviousUpTime = time;
+ mCallback.onUserInteractionStopped();
+ }
private boolean isDeltaInBounds(int startAngle, int deltaAngle) {
return getBoundIfExceeds(startAngle, deltaAngle) == Integer.MIN_VALUE;
@@ -766,9 +776,11 @@ public class ZoomRing extends View {
}
}
- int deltaAngle = getDelta(mThumbAngle, touchAngle, useDirection, ccw);
- mAcculumalatedTrailAngle += Math.toDegrees(deltaAngle / (double) RADIAN_INT_MULTIPLIER);
-
+ if (DRAW_TRAIL) {
+ int deltaAngle = getDelta(mThumbAngle, touchAngle, useDirection, ccw);
+ mAcculumalatedTrailAngle += Math.toDegrees(deltaAngle / (double) RADIAN_INT_MULTIPLIER);
+ }
+
if (animateThumbToNewAngle) {
if (useDirection) {
setThumbAngleAnimated(touchAngle, 0, ccw);
@@ -851,15 +863,10 @@ public class ZoomRing extends View {
if (DRAW_TRAIL) {
mTrail.draw(canvas);
}
-
- // If we aren't near the bounds, draw the corresponding arrows
- int callbackAngle = mPreviousCallbackAngle;
- if (callbackAngle < mThumbCwBound - RADIAN_INT_ERROR ||
- callbackAngle > mThumbCwBound + RADIAN_INT_ERROR) {
+ if ((mThumbArrowsToDraw & THUMB_ARROW_PLUS) != 0) {
mThumbPlusArrowDrawable.draw(canvas);
}
- if (callbackAngle < mThumbCcwBound - RADIAN_INT_ERROR ||
- callbackAngle > mThumbCcwBound + RADIAN_INT_ERROR) {
+ if ((mThumbArrowsToDraw & THUMB_ARROW_MINUS) != 0) {
mThumbMinusArrowDrawable.draw(canvas);
}
mThumbDrawable.draw(canvas);
@@ -875,8 +882,21 @@ public class ZoomRing extends View {
public void setThumbArrowsVisible(boolean visible) {
if (visible) {
mThumbArrowsAlpha = 255;
- mThumbPlusArrowDrawable.setAlpha(255);
- mThumbMinusArrowDrawable.setAlpha(255);
+ int callbackAngle = mPreviousCallbackAngle;
+ if (callbackAngle < mThumbCwBound - RADIAN_INT_ERROR ||
+ callbackAngle > mThumbCwBound + RADIAN_INT_ERROR) {
+ mThumbPlusArrowDrawable.setAlpha(255);
+ mThumbArrowsToDraw |= THUMB_ARROW_PLUS;
+ } else {
+ mThumbArrowsToDraw &= ~THUMB_ARROW_PLUS;
+ }
+ if (callbackAngle < mThumbCcwBound - RADIAN_INT_ERROR ||
+ callbackAngle > mThumbCcwBound + RADIAN_INT_ERROR) {
+ mThumbMinusArrowDrawable.setAlpha(255);
+ mThumbArrowsToDraw |= THUMB_ARROW_MINUS;
+ } else {
+ mThumbArrowsToDraw &= ~THUMB_ARROW_MINUS;
+ }
invalidate();
} else if (mThumbArrowsAlpha == 255) {
// Only start fade if we're fully visible (otherwise another fade is happening already)
@@ -886,17 +906,24 @@ public class ZoomRing extends View {
}
private void onThumbArrowsFadeTick() {
- if (mThumbArrowsAlpha <= 0) return;
+ if (mThumbArrowsAlpha <= 0) {
+ mThumbArrowsToDraw = 0;
+ return;
+ }
mThumbArrowsAlpha = (int)
(255 - (255 * (SystemClock.elapsedRealtime() - mThumbArrowsFadeStartTime)
/ THUMB_ARROWS_FADE_DURATION));
if (mThumbArrowsAlpha < 0) mThumbArrowsAlpha = 0;
- mThumbPlusArrowDrawable.setAlpha(mThumbArrowsAlpha);
- mThumbMinusArrowDrawable.setAlpha(mThumbArrowsAlpha);
- invalidateDrawable(mThumbPlusArrowDrawable);
- invalidateDrawable(mThumbMinusArrowDrawable);
-
+ if ((mThumbArrowsToDraw & THUMB_ARROW_PLUS) != 0) {
+ mThumbPlusArrowDrawable.setAlpha(mThumbArrowsAlpha);
+ invalidateDrawable(mThumbPlusArrowDrawable);
+ }
+ if ((mThumbArrowsToDraw & THUMB_ARROW_MINUS) != 0) {
+ mThumbMinusArrowDrawable.setAlpha(mThumbArrowsAlpha);
+ invalidateDrawable(mThumbMinusArrowDrawable);
+ }
+
if (!mHandler.hasMessages(MSG_THUMB_ARROWS_FADE_TICK)) {
mHandler.sendEmptyMessage(MSG_THUMB_ARROWS_FADE_TICK);
}
diff --git a/core/java/android/widget/ZoomRingController.java b/core/java/android/widget/ZoomRingController.java
index 31074b6..2e97fda 100644
--- a/core/java/android/widget/ZoomRingController.java
+++ b/core/java/android/widget/ZoomRingController.java
@@ -57,7 +57,7 @@ import android.view.animation.DecelerateInterpolator;
public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
View.OnTouchListener, View.OnKeyListener {
- private static final int ZOOM_RING_RADIUS_INSET = 10;
+ private static final int ZOOM_RING_RADIUS_INSET = 24;
private static final int ZOOM_RING_RECENTERING_DURATION = 500;
@@ -79,7 +79,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
private static final int MAX_PAN_GAP = 20;
private static final int MAX_INITIATE_PAN_GAP = 10;
// TODO view config
- private static final int INITIATE_PAN_DELAY = 400;
+ private static final int INITIATE_PAN_DELAY = 300;
private static final String SETTING_NAME_SHOWN_TOAST = "shown_zoom_ring_toast";
@@ -146,7 +146,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
private int mZoomRingHeight;
/** Invokes panning of owner view if the zoom ring is touching an edge. */
- private Panner mPanner = new Panner();
+ private Panner mPanner;
private long mTouchingEdgeStartTime;
private boolean mPanningEnabledForThisInteraction;
@@ -241,6 +241,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
mContext = context;
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ mPanner = new Panner();
mOwnerView = ownerView;
mZoomRing = new ZoomRing(context);
@@ -389,6 +390,8 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
};
}
+ mPanningArrows.setAnimation(null);
+
mHandler.post(mPostedVisibleInitializer);
// Handle configuration changes when visible
@@ -409,12 +412,13 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
} else {
mOwnerView.setOnTouchListener(null);
}
-
+
// No longer care about configuration changes
mContext.unregisterReceiver(mConfigurationChangedReceiver);
mWindowManager.removeView(mContainer);
-
+ mHandler.removeCallbacks(mPostedVisibleInitializer);
+
if (mCallback != null) {
mCallback.onVisibilityChanged(false);
}
@@ -464,6 +468,9 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
public boolean handleDoubleTapEvent(MotionEvent event) {
int action = event.getAction();
+ // TODO: make sure this works well with the
+ // ownerView.setOnTouchListener(this) instead of window receiving
+ // touches
if (action == MotionEvent.ACTION_DOWN) {
mTouchMode = TOUCH_MODE_WAITING_FOR_TAP_DRAG_MOVEMENT;
int x = (int) event.getX();
@@ -493,6 +500,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
mViewConfig.getScaledTouchSlop()) {
mZoomRing.setTapDragMode(true, x, y);
mTouchMode = TOUCH_MODE_FORWARDING_FOR_TAP_DRAG;
+ setTouchTargetView(mZoomRing);
}
return true;
@@ -587,7 +595,6 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
public void onZoomRingMovingStarted() {
mScroller.abortAnimation();
- mPanningEnabledForThisInteraction = false;
mTouchingEdgeStartTime = 0;
if (mCallback != null) {
mCallback.onBeginPan();
@@ -658,6 +665,8 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
if (!horizontalPanning) {
// Neither are panning, reset any timer to start pan mode
mTouchingEdgeStartTime = 0;
+ mPanningEnabledForThisInteraction = false;
+ mPanner.stop();
}
}
}
@@ -752,6 +761,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
// The ring was dismissed but we need to throw away all events until the up
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
mOwnerView.setOnTouchListener(null);
+ setTouchTargetView(null);
mReleaseTouchListenerOnUp = false;
}
@@ -763,16 +773,13 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
switch (action) {
case MotionEvent.ACTION_DOWN:
- targetView = mTouchTargetView =
- getViewForTouch((int) event.getRawX(), (int) event.getRawY());
- if (targetView != null) {
- targetView.getLocationInWindow(mTouchTargetLocationInWindow);
- }
+ targetView = getViewForTouch((int) event.getRawX(), (int) event.getRawY());
+ setTouchTargetView(targetView);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
- mTouchTargetView = null;
+ setTouchTargetView(null);
break;
}
@@ -799,6 +806,13 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
}
}
+ private void setTouchTargetView(View view) {
+ mTouchTargetView = view;
+ if (view != null) {
+ view.getLocationInWindow(mTouchTargetLocationInWindow);
+ }
+ }
+
/**
* Returns the View that should receive a touch at the given coordinates.
*
@@ -950,6 +964,22 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
}
}
+ public void setPannerStartVelocity(float startVelocity) {
+ mPanner.mStartVelocity = startVelocity;
+ }
+
+ public void setPannerAcceleration(float acceleration) {
+ mPanner.mAcceleration = acceleration;
+ }
+
+ public void setPannerMaxVelocity(float maxVelocity) {
+ mPanner.mMaxVelocity = maxVelocity;
+ }
+
+ public void setPannerStartAcceleratingDuration(int duration) {
+ mPanner.mStartAcceleratingDuration = duration;
+ }
+
private class Panner implements Runnable {
private static final int RUN_DELAY = 15;
private static final float STOP_SLOWDOWN = 0.8f;
@@ -967,6 +997,13 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
/** The time of the last callback to pan the map/browser/etc. */
private long mPreviousCallbackTime;
+ // TODO Adjust to be DPI safe
+ private float mStartVelocity = 135;
+ private float mAcceleration = 160;
+ private float mMaxVelocity = 1000;
+ private int mStartAcceleratingDuration = 700;
+ private float mVelocity;
+
/** -100 (full left) to 0 (none) to 100 (full right) */
public void setHorizontalStrength(int horizontalStrength) {
if (mHorizontalStrength == 0 && mVerticalStrength == 0 && horizontalStrength != 0) {
@@ -1013,11 +1050,12 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
boolean firstRun = mPreviousCallbackTime == 0;
long curTime = SystemClock.elapsedRealtime();
- int panAmount = getPanAmount(mStartTime, mPreviousCallbackTime, curTime);
+ int panAmount = getPanAmount(mPreviousCallbackTime, curTime);
mPreviousCallbackTime = curTime;
if (firstRun) {
mStartTime = curTime;
+ mVelocity = mStartVelocity;
} else {
int panX = panAmount * mHorizontalStrength / 100;
int panY = panAmount * mVerticalStrength / 100;
@@ -1030,12 +1068,22 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
mUiHandler.postDelayed(this, RUN_DELAY);
}
- // TODO make setter for this value so zoom clients can have different pan rates, if they want
- private static final int PAN_VELOCITY_PX_S = 30;
- private int getPanAmount(long startTime, long previousTime, long currentTime) {
- return (int) ((currentTime - previousTime) * PAN_VELOCITY_PX_S / 100);
+ private int getPanAmount(long previousTime, long currentTime) {
+ if (mVelocity > mMaxVelocity) {
+ mVelocity = mMaxVelocity;
+ } else if (mVelocity < mMaxVelocity) {
+ // See if it's time to add in some acceleration
+ if (currentTime - mStartTime > mStartAcceleratingDuration) {
+ mVelocity += (currentTime - previousTime) * mAcceleration / 1000;
+ }
+ }
+
+ return (int) ((currentTime - previousTime) * mVelocity) / 1000;
}
+
}
+
+
public interface OnZoomListener {
void onBeginDrag();