diff options
Diffstat (limited to 'core/java')
17 files changed, 202 insertions, 130 deletions
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index 9ebbe03..ddd7f7c 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -37,6 +37,14 @@ import com.android.internal.os.HandlerCaller; * etc. Such a service can optionally request the capability for querying the content * of the active window. Development of an accessibility service requires extending this * class and implementing its abstract methods. + * + * <div class="special reference"> + * <h3>Developer Guides</h3> + * <p>For more information about creating AccessibilityServices, read the + * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a> + * developer guide.</p> + * </div> + * * <h3>Lifecycle</h3> * <p> * The lifecycle of an accessibility service is managed exclusively by the system and diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java index b55fda4..8e53431 100644 --- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java +++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java @@ -42,6 +42,13 @@ import java.io.IOException; * {@link AccessibilityService} for {@link android.view.accessibility.AccessibilityEvent}s * according to the information encapsulated in this class. * + * <div class="special reference"> + * <h3>Developer Guides</h3> + * <p>For more information about creating AccessibilityServices, read the + * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a> + * developer guide.</p> + * </div> + * * @see AccessibilityService * @see android.view.accessibility.AccessibilityEvent * @see android.view.accessibility.AccessibilityManager diff --git a/core/java/android/app/DatePickerDialog.java b/core/java/android/app/DatePickerDialog.java index bf8fde0..c62e5cf 100644 --- a/core/java/android/app/DatePickerDialog.java +++ b/core/java/android/app/DatePickerDialog.java @@ -92,8 +92,7 @@ public class DatePickerDialog extends AlertDialog implements OnClickListener, mCallBack = callBack; Context themeContext = getContext(); - setButton(BUTTON_POSITIVE, themeContext.getText(R.string.date_time_set), this); - setButton(BUTTON_NEGATIVE, themeContext.getText(R.string.cancel), (OnClickListener) null); + setButton(BUTTON_POSITIVE, themeContext.getText(R.string.date_time_done), this); setIcon(0); setTitle(R.string.date_picker_dialog_title); @@ -106,11 +105,7 @@ public class DatePickerDialog extends AlertDialog implements OnClickListener, } public void onClick(DialogInterface dialog, int which) { - if (mCallBack != null) { - mDatePicker.clearFocus(); - mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(), - mDatePicker.getMonth(), mDatePicker.getDayOfMonth()); - } + tryNotifyDateSet(); } public void onDateChanged(DatePicker view, int year, @@ -138,6 +133,20 @@ public class DatePickerDialog extends AlertDialog implements OnClickListener, mDatePicker.updateDate(year, monthOfYear, dayOfMonth); } + private void tryNotifyDateSet() { + if (mCallBack != null) { + mDatePicker.clearFocus(); + mCallBack.onDateSet(mDatePicker, mDatePicker.getYear(), + mDatePicker.getMonth(), mDatePicker.getDayOfMonth()); + } + } + + @Override + protected void onStop() { + tryNotifyDateSet(); + super.onStop(); + } + @Override public Bundle onSaveInstanceState() { Bundle state = super.onSaveInstanceState(); diff --git a/core/java/android/app/TimePickerDialog.java b/core/java/android/app/TimePickerDialog.java index 353b415..d773bc8 100644 --- a/core/java/android/app/TimePickerDialog.java +++ b/core/java/android/app/TimePickerDialog.java @@ -96,9 +96,7 @@ public class TimePickerDialog extends AlertDialog setTitle(R.string.time_picker_dialog_title); Context themeContext = getContext(); - setButton(BUTTON_POSITIVE, themeContext.getText(R.string.date_time_set), this); - setButton(BUTTON_NEGATIVE, themeContext.getText(R.string.cancel), - (OnClickListener) null); + setButton(BUTTON_POSITIVE, themeContext.getText(R.string.date_time_done), this); LayoutInflater inflater = (LayoutInflater) themeContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); @@ -114,11 +112,7 @@ public class TimePickerDialog extends AlertDialog } public void onClick(DialogInterface dialog, int which) { - if (mCallback != null) { - mTimePicker.clearFocus(); - mCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(), - mTimePicker.getCurrentMinute()); - } + tryNotifyTimeSet(); } public void updateTime(int hourOfDay, int minutOfHour) { @@ -130,6 +124,20 @@ public class TimePickerDialog extends AlertDialog /* do nothing */ } + private void tryNotifyTimeSet() { + if (mCallback != null) { + mTimePicker.clearFocus(); + mCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(), + mTimePicker.getCurrentMinute()); + } + } + + @Override + protected void onStop() { + tryNotifyTimeSet(); + super.onStop(); + } + @Override public Bundle onSaveInstanceState() { Bundle state = super.onSaveInstanceState(); diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java index 3c0ee12..26a5b26 100644 --- a/core/java/android/view/LayoutInflater.java +++ b/core/java/android/view/LayoutInflater.java @@ -583,7 +583,14 @@ public abstract class LayoutInflater { Object[] args = mConstructorArgs; args[1] = attrs; - return constructor.newInstance(args); + + final View view = constructor.newInstance(args); + if (view instanceof ViewStub) { + // always use ourselves when inflating ViewStub later + final ViewStub viewStub = (ViewStub) view; + viewStub.setLayoutInflater(this); + } + return view; } catch (NoSuchMethodException e) { InflateException ie = new InflateException(attrs.getPositionDescription() diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 18e1697..69d7655 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -15901,6 +15901,12 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * classes i.e. classes in package android.view, that would like their * applications to be backwards compatible. * </p> + * <div class="special reference"> + * <h3>Developer Guides</h3> + * <p>For more information about making applications accessible, read the + * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a> + * developer guide.</p> + * </div> * <p> * A scenario in which a developer would like to use an accessibility delegate * is overriding a method introduced in a later API version then the minimal API diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java index 20183ee..b9924c7 100644 --- a/core/java/android/view/ViewConfiguration.java +++ b/core/java/android/view/ViewConfiguration.java @@ -31,14 +31,14 @@ import android.util.SparseArray; public class ViewConfiguration { /** * Expected bit depth of the display panel. - * + * * @hide */ public static final float PANEL_BIT_DEPTH = 24; /** * Minimum alpha required for a view to draw. - * + * * @hide */ public static final float ALPHA_THRESHOLD = 0.5f / PANEL_BIT_DEPTH; @@ -72,8 +72,8 @@ public class ViewConfiguration { * Defines the duration in milliseconds of the pressed state in child * components. */ - private static final int PRESSED_STATE_DURATION = 125; - + private static final int PRESSED_STATE_DURATION = 64; + /** * Defines the default duration in milliseconds before a press turns into * a long press @@ -91,18 +91,18 @@ public class ViewConfiguration { * lock screen, etc). */ private static final int GLOBAL_ACTIONS_KEY_TIMEOUT = 500; - + /** - * Defines the duration in milliseconds we will wait to see if a touch event + * Defines the duration in milliseconds we will wait to see if a touch event * is a tap or a scroll. If the user does not move within this interval, it is - * considered to be a tap. + * considered to be a tap. */ private static final int TAP_TIMEOUT = 180; - + /** - * Defines the duration in milliseconds we will wait to see if a touch event + * Defines the duration in milliseconds we will wait to see if a touch event * is a jump tap. If the user does not complete the jump tap within this interval, it is - * considered to be a tap. + * considered to be a tap. */ private static final int JUMP_TAP_TIMEOUT = 500; @@ -128,7 +128,7 @@ public class ViewConfiguration { private static final int HOVER_TAP_SLOP = 20; /** - * Defines the duration in milliseconds we want to display zoom controls in response + * Defines the duration in milliseconds we want to display zoom controls in response * to a user panning within an application. */ private static final int ZOOM_CONTROLS_TIMEOUT = 3000; @@ -137,7 +137,7 @@ public class ViewConfiguration { * Inset in dips to look for touchable content when the user touches the edge of the screen */ private static final int EDGE_SLOP = 12; - + /** * Distance a touch can wander before we think the user is scrolling in dips. * Note that this value defined here is only used as a fallback by legacy/misbehaving @@ -150,7 +150,7 @@ public class ViewConfiguration { * the characteristics of the touch panel and firmware. */ private static final int TOUCH_SLOP = 8; - + /** * Distance the first touch can wander before we stop considering this event a double tap * (in dips) @@ -170,12 +170,12 @@ public class ViewConfiguration { * config_viewConfigurationTouchSlop * 2 when provided with a Context. */ private static final int PAGING_TOUCH_SLOP = TOUCH_SLOP * 2; - + /** * Distance in dips between the first touch and second touch to still be considered a double tap */ private static final int DOUBLE_TAP_SLOP = 100; - + /** * Distance in dips a touch needs to be outside of a window's bounds for it to * count as outside for purposes of dismissing the window. @@ -186,7 +186,7 @@ public class ViewConfiguration { * Minimum velocity to initiate a fling, as measured in dips per second */ private static final int MINIMUM_FLING_VELOCITY = 50; - + /** * Maximum velocity to initiate a fling, as measured in dips per second */ @@ -281,7 +281,7 @@ public class ViewConfiguration { * * @param context The application context used to initialize this view configuration. * - * @see #get(android.content.Context) + * @see #get(android.content.Context) * @see android.util.DisplayMetrics */ private ViewConfiguration(Context context) { @@ -383,7 +383,7 @@ public class ViewConfiguration { public static int getScrollDefaultDelay() { return SCROLL_BAR_DEFAULT_DELAY; } - + /** * @return the length of the fading edges in dips * @@ -435,7 +435,7 @@ public class ViewConfiguration { /** * @return the duration in milliseconds we will wait to see if a touch event * is a tap or a scroll. If the user does not move within this interval, it is - * considered to be a tap. + * considered to be a tap. */ public static int getTapTimeout() { return TAP_TIMEOUT; @@ -444,12 +444,12 @@ public class ViewConfiguration { /** * @return the duration in milliseconds we will wait to see if a touch event * is a jump tap. If the user does not move within this interval, it is - * considered to be a tap. + * considered to be a tap. */ public static int getJumpTapTimeout() { return JUMP_TAP_TIMEOUT; } - + /** * @return the duration in milliseconds between the first tap's up event and * the second tap's down event for an interaction to be considered a @@ -514,7 +514,7 @@ public class ViewConfiguration { public int getScaledTouchSlop() { return mTouchSlop; } - + /** * @return Distance in pixels the first touch can wander before we do not consider this a * potential double tap event @@ -543,7 +543,7 @@ public class ViewConfiguration { public static int getDoubleTapSlop() { return DOUBLE_TAP_SLOP; } - + /** * @return Distance in pixels between the first touch and second touch to still be * considered a double tap @@ -595,7 +595,7 @@ public class ViewConfiguration { public int getScaledWindowTouchSlop() { return mWindowTouchSlop; } - + /** * @return Minimum velocity to initiate a fling, as measured in dips per second. * @@ -629,7 +629,7 @@ public class ViewConfiguration { public int getScaledMaximumFlingVelocity() { return mMaximumFlingVelocity; } - + /** * The maximum drawing cache size expressed in bytes. * @@ -671,7 +671,7 @@ public class ViewConfiguration { /** * The amount of time that the zoom controls should be * displayed on the screen expressed in milliseconds. - * + * * @return the time the zoom controls should be visible expressed * in milliseconds. */ @@ -692,7 +692,7 @@ public class ViewConfiguration { /** * The amount of friction applied to scrolls and flings. - * + * * @return A scalar dimensionless value representing the coefficient of * friction. */ diff --git a/core/java/android/view/ViewStub.java b/core/java/android/view/ViewStub.java index d5e9af4..69a26c2 100644 --- a/core/java/android/view/ViewStub.java +++ b/core/java/android/view/ViewStub.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.util.AttributeSet; +import android.widget.RemoteViews.RemoteView; import com.android.internal.R; @@ -66,12 +67,14 @@ import java.lang.ref.WeakReference; * @attr ref android.R.styleable#ViewStub_inflatedId * @attr ref android.R.styleable#ViewStub_layout */ +@RemoteView public final class ViewStub extends View { private int mLayoutResource = 0; private int mInflatedId; private WeakReference<View> mInflatedViewRef; + private LayoutInflater mInflater; private OnInflateListener mInflateListener; public ViewStub(Context context) { @@ -140,6 +143,7 @@ public final class ViewStub extends View { * @see #getInflatedId() * @attr ref android.R.styleable#ViewStub_inflatedId */ + @android.view.RemotableViewMethod public void setInflatedId(int inflatedId) { mInflatedId = inflatedId; } @@ -172,10 +176,26 @@ public final class ViewStub extends View { * @see #inflate() * @attr ref android.R.styleable#ViewStub_layout */ + @android.view.RemotableViewMethod public void setLayoutResource(int layoutResource) { mLayoutResource = layoutResource; } + /** + * Set {@link LayoutInflater} to use in {@link #inflate()}, or {@code null} + * to use the default. + */ + public void setLayoutInflater(LayoutInflater inflater) { + mInflater = inflater; + } + + /** + * Get current {@link LayoutInflater} used in {@link #inflate()}. + */ + public LayoutInflater getLayoutInflater() { + return mInflater; + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(0, 0); @@ -199,6 +219,7 @@ public final class ViewStub extends View { * @see #inflate() */ @Override + @android.view.RemotableViewMethod public void setVisibility(int visibility) { if (mInflatedViewRef != null) { View view = mInflatedViewRef.get(); @@ -228,7 +249,12 @@ public final class ViewStub extends View { if (viewParent != null && viewParent instanceof ViewGroup) { if (mLayoutResource != 0) { final ViewGroup parent = (ViewGroup) viewParent; - final LayoutInflater factory = LayoutInflater.from(mContext); + final LayoutInflater factory; + if (mInflater != null) { + factory = mInflater; + } else { + factory = LayoutInflater.from(mContext); + } final View view = factory.inflate(mLayoutResource, parent, false); diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java index 58844fc..0998c80 100644 --- a/core/java/android/view/accessibility/AccessibilityEvent.java +++ b/core/java/android/view/accessibility/AccessibilityEvent.java @@ -59,6 +59,12 @@ import java.util.List; * by this class. For each event type there is a corresponding constant defined * in this class. Follows a specification of the event types and their associated properties: * </p> + * <div class="special reference"> + * <h3>Developer Guides</h3> + * <p>For more information about creating and processing AccessibilityEvents, read the + * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a> + * developer guide.</p> + * </div> * <p> * <b>VIEW TYPES</b></br> * </p> diff --git a/core/java/android/view/accessibility/AccessibilityEventSource.java b/core/java/android/view/accessibility/AccessibilityEventSource.java index f11880b..525ba9e 100644 --- a/core/java/android/view/accessibility/AccessibilityEventSource.java +++ b/core/java/android/view/accessibility/AccessibilityEventSource.java @@ -18,6 +18,13 @@ package android.view.accessibility; /** * This interface is implemented by classes source of {@link AccessibilityEvent}s. + * + * <div class="special reference"> + * <h3>Developer Guides</h3> + * <p>For more information about making applications accessible, read the + * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a> + * developer guide.</p> + * </div> */ public interface AccessibilityEventSource { diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java index 03c6211..f616dca 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java @@ -43,6 +43,12 @@ import java.util.List; * details about how to obtain a handle to window content as a tree of accessibility * node info as well as familiarizing with the security model. * </p> + * <div class="special reference"> + * <h3>Developer Guides</h3> + * <p>For more information about making applications accessible, read the + * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a> + * developer guide.</p> + * </div> * * @see android.accessibilityservice.AccessibilityService * @see AccessibilityEvent diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java index bc6074f..d25b3db 100644 --- a/core/java/android/view/accessibility/AccessibilityRecord.java +++ b/core/java/android/view/accessibility/AccessibilityRecord.java @@ -41,6 +41,13 @@ import java.util.List; * event types. For detailed information please refer to {@link AccessibilityEvent}. * </p> * + * <div class="special reference"> + * <h3>Developer Guides</h3> + * <p>For more information about creating and processing AccessibilityRecords, read the + * <a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a> + * developer guide.</p> + * </div> + * * @see AccessibilityEvent * @see AccessibilityManager * @see android.accessibilityservice.AccessibilityService diff --git a/core/java/android/view/accessibility/package.html b/core/java/android/view/accessibility/package.html index 4afafd3..c2da0ae 100644 --- a/core/java/android/view/accessibility/package.html +++ b/core/java/android/view/accessibility/package.html @@ -35,5 +35,12 @@ changes etc. Parties interested in handling accessibility events implement and register an accessibility service which extends {@link android.accessibilityservice.AccessibilityService}. </p> +<div class="special reference"> +<h3>Developer Guides</h3> +<p>For more information about making applications accessible, read the +<a href="{@docRoot}guide/topics/ui/accessibility/index.html">Accessibility</a> +developer guide.</p> +</div> + </body> </html> diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 422b48d..9492e38 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -1913,13 +1913,6 @@ public class WebView extends AbsoluteLayout } @Override - protected boolean drawChild(Canvas canvas, View child, long drawingTime) { - // Not using short-circuit OR: provider does suppress base-class call. - return mProvider.getViewDelegate().drawChild(canvas, child, drawingTime) | - super.drawChild(canvas, child, drawingTime); - } - - @Override protected void onDraw(Canvas canvas) { mProvider.getViewDelegate().onDraw(canvas); } diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java index 45c5fa0..4c118ac 100644 --- a/core/java/android/webkit/WebViewClassic.java +++ b/core/java/android/webkit/WebViewClassic.java @@ -2011,7 +2011,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc if (mWebView instanceof TitleBarDelegate) { return ((TitleBarDelegate) mWebView).getTitleHeight(); } - return mTitleBar != null ? mTitleBar.getHeight() : 0; + return 0; } /** @@ -2943,50 +2943,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } /** - * A title bar which is embedded in this WebView, and scrolls along with it - * vertically, but not horizontally. - */ - private View mTitleBar; - - /** - * the title bar rendering gravity - */ - private int mTitleGravity; - - /** - * Add or remove a title bar to be embedded into the WebView, and scroll - * along with it vertically, while remaining in view horizontally. Pass - * null to remove the title bar from the WebView, and return to drawing - * the WebView normally without translating to account for the title bar. - */ - public void setEmbeddedTitleBar(View v) { - if (mWebView instanceof TitleBarDelegate) { - ((TitleBarDelegate) mWebView).onSetEmbeddedTitleBar(v); - } - if (mTitleBar == v) return; - if (mTitleBar != null) { - mWebView.removeView(mTitleBar); - } - if (null != v) { - mWebView.addView(v, new AbsoluteLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT, 0, 0)); - } - mTitleBar = v; - } - - /** - * Set where to render the embedded title bar - * NO_GRAVITY at the top of the page - * TOP at the top of the screen - */ - public void setTitleBarGravity(int gravity) { - mTitleGravity = gravity; - // force refresh - invalidate(); - } - - /** * Given a distance in view space, convert it to content space. Note: this * does not reflect translation, just scaling, so this should not be called * with coordinates, but should be called for dimensions like width or @@ -4184,7 +4140,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc // animate the title bar off screen slowly enough that the user can see // it. if (cx == 0 && cy == 1 && getScrollX() == 0 && getScrollY() == 0 - && mTitleBar != null) { + && getTitleHeight() > 0) { // FIXME: 100 should be defined somewhere as our max progress. if (getProgress() < 100) { // Wait to scroll the title bar off screen until the page has @@ -4401,24 +4357,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } } - @Override - public boolean drawChild(Canvas canvas, View child, long drawingTime) { - if (child == mTitleBar) { - // When drawing the title bar, move it horizontally to always show - // at the top of the WebView. - mTitleBar.offsetLeftAndRight(getScrollX() - mTitleBar.getLeft()); - int newTop = 0; - if (mTitleGravity == Gravity.NO_GRAVITY) { - newTop = Math.min(0, getScrollY()); - } else if (mTitleGravity == Gravity.TOP) { - newTop = getScrollY(); - } - mTitleBar.setBottom(newTop + mTitleBar.getHeight()); - mTitleBar.setTop(newTop); - } - return false; // We never call invalidate(), so unconditionally returning false. - } - private void drawContent(Canvas canvas) { if (mDrawHistory) { canvas.scale(mZoomManager.getScale(), mZoomManager.getScale()); @@ -4583,9 +4521,8 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc .getUseWebViewBackgroundForOverscrollBackground()) { drawOverScrollBackground(canvas); } - if (mTitleBar != null) { - canvas.translate(0, getTitleHeight()); - } + + canvas.translate(0, getTitleHeight()); drawContent(canvas); canvas.restoreToCount(saveCount); diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java index f049198..74a215c 100644 --- a/core/java/android/webkit/WebViewProvider.java +++ b/core/java/android/webkit/WebViewProvider.java @@ -287,8 +287,6 @@ public interface WebViewProvider { public void onWindowVisibilityChanged(int visibility); - public boolean drawChild(Canvas canvas, View child, long drawingTime); - public void onDraw(Canvas canvas); public void setLayoutParams(LayoutParams layoutParams); diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java index 4e56cd6..d897a39 100644 --- a/core/java/android/widget/NumberPicker.java +++ b/core/java/android/widget/NumberPicker.java @@ -112,10 +112,10 @@ public class NumberPicker extends LinearLayout { private static final int SELECTOR_ADJUSTMENT_DURATION_MILLIS = 800; /** - * The duration of scrolling to the next/previous value while changing the - * current value by one, i.e. increment or decrement. + * The duration of scrolling to the next/previous value while snapping to + * a given position. */ - private static final int CHANGE_CURRENT_BY_ONE_SCROLL_DURATION = 300; + private static final int SNAP_SCROLL_DURATION = 300; /** * The strength of fading in the top and bottom while drawing the selector. @@ -140,7 +140,7 @@ public class NumberPicker extends LinearLayout { /** * Coefficient for adjusting touch scroll distance. */ - private static final float TOUCH_SCROLL_DECELERATION_COEFFICIENT = 2.5f; + private static final float TOUCH_SCROLL_DECELERATION_COEFFICIENT = 2.0f; /** * The resource id for the default layout. @@ -152,7 +152,7 @@ public class NumberPicker extends LinearLayout { */ private static final char[] DIGIT_CHARACTERS = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' - }; + }; /** * Constant for unspecified size. @@ -838,7 +838,13 @@ public class NumberPicker extends LinearLayout { if (absDeltaMoveY > mMinFlingDistance) { fling(initialVelocity); } else { - changeValueByOne(deltaMove < 0); + final int normalizedDeltaMove = + (int) (absDeltaMoveY / TOUCH_SCROLL_DECELERATION_COEFFICIENT); + if (normalizedDeltaMove < mSelectorElementHeight) { + snapToNextValue(deltaMove < 0); + } else { + snapToClosestValue(); + } } onScrollStateChange(OnScrollListener.SCROLL_STATE_FLING); } else { @@ -1509,11 +1515,9 @@ public class NumberPicker extends LinearLayout { } mPreviousScrollerY = 0; if (increment) { - mFlingScroller.startScroll(0, 0, 0, -mSelectorElementHeight, - CHANGE_CURRENT_BY_ONE_SCROLL_DURATION); + mFlingScroller.startScroll(0, 0, 0, -mSelectorElementHeight, SNAP_SCROLL_DURATION); } else { - mFlingScroller.startScroll(0, 0, 0, mSelectorElementHeight, - CHANGE_CURRENT_BY_ONE_SCROLL_DURATION); + mFlingScroller.startScroll(0, 0, 0, mSelectorElementHeight, SNAP_SCROLL_DURATION); } invalidate(); } else { @@ -1902,6 +1906,42 @@ public class NumberPicker extends LinearLayout { return false; } + private void snapToNextValue(boolean increment) { + int deltaY = mCurrentScrollOffset - mInitialScrollOffset; + int amountToScroll = 0; + if (deltaY != 0) { + mPreviousScrollerY = 0; + if (deltaY > 0) { + if (increment) { + amountToScroll = - deltaY; + } else { + amountToScroll = mSelectorElementHeight - deltaY; + } + } else { + if (increment) { + amountToScroll = - mSelectorElementHeight - deltaY; + } else { + amountToScroll = - deltaY; + } + } + mFlingScroller.startScroll(0, 0, 0, amountToScroll, SNAP_SCROLL_DURATION); + invalidate(); + } + } + + private void snapToClosestValue() { + // adjust to the closest value + int deltaY = mInitialScrollOffset - mCurrentScrollOffset; + if (deltaY != 0) { + mPreviousScrollerY = 0; + if (Math.abs(deltaY) > mSelectorElementHeight / 2) { + deltaY += (deltaY > 0) ? -mSelectorElementHeight : mSelectorElementHeight; + } + mFlingScroller.startScroll(0, 0, 0, deltaY, SNAP_SCROLL_DURATION); + invalidate(); + } + } + /** * Command for setting the input text selection. */ |
