blob: 7674837e3a1291d78f867fd9c9f42eeb45e8a9f5 [file] [log] [blame]
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -07001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.widget;
18
19import android.content.Context;
20import android.content.res.TypedArray;
21import android.graphics.Canvas;
22import android.graphics.Rect;
23import android.graphics.drawable.Drawable;
alanvc826b7d2012-05-16 14:19:21 -070024import android.os.Bundle;
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070025import android.util.AttributeSet;
The Android Open Source Projectb7986892009-01-09 17:51:23 -080026import android.view.KeyEvent;
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070027import android.view.MotionEvent;
Adam Powell10298662011-08-14 18:26:30 -070028import android.view.ViewConfiguration;
Svetoslav Ganov8a78fd42012-01-17 14:36:46 -080029import android.view.accessibility.AccessibilityEvent;
30import android.view.accessibility.AccessibilityNodeInfo;
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070031
32public abstract class AbsSeekBar extends ProgressBar {
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070033 private Drawable mThumb;
34 private int mThumbOffset;
35
36 /**
37 * On touch, this offset plus the scaled value from the position of the
38 * touch will form the progress value. Usually 0.
39 */
40 float mTouchProgressOffset;
41
42 /**
43 * Whether this is user seekable.
44 */
45 boolean mIsUserSeekable = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046
47 /**
48 * On key presses (right or left), the amount to increment/decrement the
49 * progress.
50 */
51 private int mKeyProgressIncrement = 1;
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070052
53 private static final int NO_ALPHA = 0xFF;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054 private float mDisabledAlpha;
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070055
Adam Powell10298662011-08-14 18:26:30 -070056 private int mScaledTouchSlop;
57 private float mTouchDownX;
58 private boolean mIsDragging;
59
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070060 public AbsSeekBar(Context context) {
61 super(context);
62 }
63
64 public AbsSeekBar(Context context, AttributeSet attrs) {
65 super(context, attrs);
66 }
67
68 public AbsSeekBar(Context context, AttributeSet attrs, int defStyle) {
69 super(context, attrs, defStyle);
70
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070071 TypedArray a = context.obtainStyledAttributes(attrs,
72 com.android.internal.R.styleable.SeekBar, defStyle, 0);
73 Drawable thumb = a.getDrawable(com.android.internal.R.styleable.SeekBar_thumb);
Daniel Sandler8d28c3b2009-08-20 13:34:02 -040074 setThumb(thumb); // will guess mThumbOffset if thumb != null...
75 // ...but allow layout to override this
Romain Guy992cc422010-01-04 15:39:40 -080076 int thumbOffset = a.getDimensionPixelOffset(
77 com.android.internal.R.styleable.SeekBar_thumbOffset, getThumbOffset());
78 setThumbOffset(thumbOffset);
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070079 a.recycle();
80
81 a = context.obtainStyledAttributes(attrs,
82 com.android.internal.R.styleable.Theme, 0, 0);
83 mDisabledAlpha = a.getFloat(com.android.internal.R.styleable.Theme_disabledAlpha, 0.5f);
84 a.recycle();
Adam Powell10298662011-08-14 18:26:30 -070085
86 mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070087 }
88
89 /**
Daniel Sandler8d28c3b2009-08-20 13:34:02 -040090 * Sets the thumb that will be drawn at the end of the progress meter within the SeekBar.
91 * <p>
92 * If the thumb is a valid drawable (i.e. not null), half its width will be
93 * used as the new thumb offset (@see #setThumbOffset(int)).
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070094 *
95 * @param thumb Drawable representing the thumb
96 */
97 public void setThumb(Drawable thumb) {
Joe Onorato2e585f72010-12-02 14:10:57 -080098 boolean needUpdate;
99 // This way, calling setThumb again with the same bitmap will result in
100 // it recalcuating mThumbOffset (if for example it the bounds of the
101 // drawable changed)
102 if (mThumb != null && thumb != mThumb) {
103 mThumb.setCallback(null);
104 needUpdate = true;
105 } else {
106 needUpdate = false;
107 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700108 if (thumb != null) {
109 thumb.setCallback(this);
Fabrice Di Meglio0af4b8b2012-06-11 18:30:05 -0700110 if (canResolveLayoutDirection()) {
Fabrice Di Meglioe56ffdc2012-09-23 14:51:16 -0700111 thumb.setLayoutDirection(getLayoutDirection());
Fabrice Di Meglio0af4b8b2012-06-11 18:30:05 -0700112 }
Daniel Sandler8d28c3b2009-08-20 13:34:02 -0400113
114 // Assuming the thumb drawable is symmetric, set the thumb offset
115 // such that the thumb will hang halfway off either edge of the
116 // progress bar.
Romain Guy992cc422010-01-04 15:39:40 -0800117 mThumbOffset = thumb.getIntrinsicWidth() / 2;
Joe Onorato2e585f72010-12-02 14:10:57 -0800118
119 // If we're updating get the new states
120 if (needUpdate &&
121 (thumb.getIntrinsicWidth() != mThumb.getIntrinsicWidth()
122 || thumb.getIntrinsicHeight() != mThumb.getIntrinsicHeight())) {
123 requestLayout();
124 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700125 }
126 mThumb = thumb;
127 invalidate();
Joe Onorato2e585f72010-12-02 14:10:57 -0800128 if (needUpdate) {
129 updateThumbPos(getWidth(), getHeight());
Adam Powell0283a552012-04-19 09:58:22 -0700130 if (thumb != null && thumb.isStateful()) {
Joe Onorato2e585f72010-12-02 14:10:57 -0800131 // Note that if the states are different this won't work.
132 // For now, let's consider that an app bug.
133 int[] state = getDrawableState();
134 thumb.setState(state);
135 }
136 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700137 }
138
139 /**
Adam Powell3004cc52012-03-21 17:50:51 -0700140 * Return the drawable used to represent the scroll thumb - the component that
141 * the user can drag back and forth indicating the current value by its position.
142 *
143 * @return The current thumb drawable
144 */
145 public Drawable getThumb() {
146 return mThumb;
147 }
148
149 /**
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700150 * @see #setThumbOffset(int)
151 */
152 public int getThumbOffset() {
153 return mThumbOffset;
154 }
155
156 /**
157 * Sets the thumb offset that allows the thumb to extend out of the range of
158 * the track.
159 *
160 * @param thumbOffset The offset amount in pixels.
161 */
162 public void setThumbOffset(int thumbOffset) {
163 mThumbOffset = thumbOffset;
164 invalidate();
165 }
166
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 /**
168 * Sets the amount of progress changed via the arrow keys.
169 *
170 * @param increment The amount to increment or decrement when the user
171 * presses the arrow keys.
172 */
173 public void setKeyProgressIncrement(int increment) {
174 mKeyProgressIncrement = increment < 0 ? -increment : increment;
175 }
176
177 /**
178 * Returns the amount of progress changed via the arrow keys.
179 * <p>
180 * By default, this will be a value that is derived from the max progress.
181 *
182 * @return The amount to increment or decrement when the user presses the
183 * arrow keys. This will be positive.
184 */
185 public int getKeyProgressIncrement() {
186 return mKeyProgressIncrement;
187 }
188
189 @Override
190 public synchronized void setMax(int max) {
191 super.setMax(max);
192
193 if ((mKeyProgressIncrement == 0) || (getMax() / mKeyProgressIncrement > 20)) {
194 // It will take the user too long to change this via keys, change it
195 // to something more reasonable
196 setKeyProgressIncrement(Math.max(1, Math.round((float) getMax() / 20)));
197 }
198 }
199
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700200 @Override
201 protected boolean verifyDrawable(Drawable who) {
202 return who == mThumb || super.verifyDrawable(who);
203 }
204
205 @Override
Dianne Hackborne2136772010-11-04 15:08:59 -0700206 public void jumpDrawablesToCurrentState() {
207 super.jumpDrawablesToCurrentState();
208 if (mThumb != null) mThumb.jumpToCurrentState();
209 }
210
211 @Override
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700212 protected void drawableStateChanged() {
213 super.drawableStateChanged();
214
215 Drawable progressDrawable = getProgressDrawable();
216 if (progressDrawable != null) {
217 progressDrawable.setAlpha(isEnabled() ? NO_ALPHA : (int) (NO_ALPHA * mDisabledAlpha));
218 }
The Android Open Source Projectb7986892009-01-09 17:51:23 -0800219
220 if (mThumb != null && mThumb.isStateful()) {
221 int[] state = getDrawableState();
222 mThumb.setState(state);
223 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700224 }
225
226 @Override
Svetoslav Ganov6518ad72011-03-18 16:19:55 -0700227 void onProgressRefresh(float scale, boolean fromUser) {
228 super.onProgressRefresh(scale, fromUser);
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700229 Drawable thumb = mThumb;
230 if (thumb != null) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700231 setThumbPos(getWidth(), thumb, scale, Integer.MIN_VALUE);
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700232 /*
233 * Since we draw translated, the drawable's bounds that it signals
234 * for invalidation won't be the actual bounds we want invalidated,
235 * so just invalidate this whole view.
236 */
237 invalidate();
238 }
239 }
240
241
242 @Override
243 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Fabrice Di Megliof37df1b2012-10-15 19:10:08 -0700244 super.onSizeChanged(w, h, oldw, oldh);
Joe Onorato2e585f72010-12-02 14:10:57 -0800245 updateThumbPos(w, h);
246 }
247
248 private void updateThumbPos(int w, int h) {
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700249 Drawable d = getCurrentDrawable();
250 Drawable thumb = mThumb;
251 int thumbHeight = thumb == null ? 0 : thumb.getIntrinsicHeight();
252 // The max height does not incorporate padding, whereas the height
253 // parameter does
254 int trackHeight = Math.min(mMaxHeight, h - mPaddingTop - mPaddingBottom);
255
256 int max = getMax();
257 float scale = max > 0 ? (float) getProgress() / (float) max : 0;
258
259 if (thumbHeight > trackHeight) {
260 if (thumb != null) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700261 setThumbPos(w, thumb, scale, 0);
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700262 }
263 int gapForCenteringTrack = (thumbHeight - trackHeight) / 2;
264 if (d != null) {
265 // Canvas will be translated by the padding, so 0,0 is where we start drawing
266 d.setBounds(0, gapForCenteringTrack,
267 w - mPaddingRight - mPaddingLeft, h - mPaddingBottom - gapForCenteringTrack
268 - mPaddingTop);
269 }
270 } else {
271 if (d != null) {
272 // Canvas will be translated by the padding, so 0,0 is where we start drawing
273 d.setBounds(0, 0, w - mPaddingRight - mPaddingLeft, h - mPaddingBottom
274 - mPaddingTop);
275 }
276 int gap = (trackHeight - thumbHeight) / 2;
277 if (thumb != null) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700278 setThumbPos(w, thumb, scale, gap);
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700279 }
280 }
281 }
282
283 /**
284 * @param gap If set to {@link Integer#MIN_VALUE}, this will be ignored and
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700285 */
The Android Open Source Project10592532009-03-18 17:39:46 -0700286 private void setThumbPos(int w, Drawable thumb, float scale, int gap) {
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700287 int available = w - mPaddingLeft - mPaddingRight;
288 int thumbWidth = thumb.getIntrinsicWidth();
289 int thumbHeight = thumb.getIntrinsicHeight();
290 available -= thumbWidth;
291
292 // The extra space for the thumb to move on the track
293 available += mThumbOffset * 2;
294
295 int thumbPos = (int) (scale * available);
296
297 int topBound, bottomBound;
298 if (gap == Integer.MIN_VALUE) {
299 Rect oldBounds = thumb.getBounds();
300 topBound = oldBounds.top;
301 bottomBound = oldBounds.bottom;
302 } else {
303 topBound = gap;
304 bottomBound = gap + thumbHeight;
305 }
306
307 // Canvas will be translated, so 0,0 is where we start drawing
Fabrice Di Meglio2b378cd2013-01-30 16:39:33 -0800308 final int left = (isLayoutRtl() && mMirrorForRtl) ? available - thumbPos : thumbPos;
Fabrice Di Meglio06849e82012-09-11 19:35:06 -0700309 thumb.setBounds(left, topBound, left + thumbWidth, bottomBound);
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700310 }
Fabrice Di Meglio0af4b8b2012-06-11 18:30:05 -0700311
Fabrice Di Meglio4457e852012-09-18 19:23:12 -0700312 /**
313 * @hide
314 */
Fabrice Di Meglio0af4b8b2012-06-11 18:30:05 -0700315 @Override
316 public void onResolveDrawables(int layoutDirection) {
317 super.onResolveDrawables(layoutDirection);
318
319 if (mThumb != null) {
320 mThumb.setLayoutDirection(layoutDirection);
321 }
322 }
323
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700324 @Override
325 protected synchronized void onDraw(Canvas canvas) {
326 super.onDraw(canvas);
327 if (mThumb != null) {
328 canvas.save();
329 // Translate the padding. For the x, we need to allow the thumb to
330 // draw in its extra space
331 canvas.translate(mPaddingLeft - mThumbOffset, mPaddingTop);
332 mThumb.draw(canvas);
333 canvas.restore();
334 }
335 }
336
337 @Override
338 protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
339 Drawable d = getCurrentDrawable();
340
341 int thumbHeight = mThumb == null ? 0 : mThumb.getIntrinsicHeight();
342 int dw = 0;
343 int dh = 0;
344 if (d != null) {
345 dw = Math.max(mMinWidth, Math.min(mMaxWidth, d.getIntrinsicWidth()));
346 dh = Math.max(mMinHeight, Math.min(mMaxHeight, d.getIntrinsicHeight()));
347 dh = Math.max(thumbHeight, dh);
348 }
349 dw += mPaddingLeft + mPaddingRight;
350 dh += mPaddingTop + mPaddingBottom;
351
Dianne Hackborn189ee182010-12-02 21:48:53 -0800352 setMeasuredDimension(resolveSizeAndState(dw, widthMeasureSpec, 0),
353 resolveSizeAndState(dh, heightMeasureSpec, 0));
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700354 }
355
356 @Override
357 public boolean onTouchEvent(MotionEvent event) {
358 if (!mIsUserSeekable || !isEnabled()) {
359 return false;
360 }
361
362 switch (event.getAction()) {
363 case MotionEvent.ACTION_DOWN:
Adam Powell10298662011-08-14 18:26:30 -0700364 if (isInScrollingContainer()) {
365 mTouchDownX = event.getX();
366 } else {
367 setPressed(true);
Adam Powell2c5b8cc2011-10-13 11:44:38 -0700368 if (mThumb != null) {
369 invalidate(mThumb.getBounds()); // This may be within the padding region
370 }
Adam Powell10298662011-08-14 18:26:30 -0700371 onStartTrackingTouch();
372 trackTouchEvent(event);
373 attemptClaimDrag();
374 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700375 break;
376
377 case MotionEvent.ACTION_MOVE:
Adam Powell10298662011-08-14 18:26:30 -0700378 if (mIsDragging) {
379 trackTouchEvent(event);
380 } else {
381 final float x = event.getX();
382 if (Math.abs(x - mTouchDownX) > mScaledTouchSlop) {
383 setPressed(true);
Adam Powell2c5b8cc2011-10-13 11:44:38 -0700384 if (mThumb != null) {
385 invalidate(mThumb.getBounds()); // This may be within the padding region
386 }
Adam Powell10298662011-08-14 18:26:30 -0700387 onStartTrackingTouch();
388 trackTouchEvent(event);
389 attemptClaimDrag();
390 }
391 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700392 break;
393
394 case MotionEvent.ACTION_UP:
Adam Powell10298662011-08-14 18:26:30 -0700395 if (mIsDragging) {
396 trackTouchEvent(event);
397 onStopTrackingTouch();
398 setPressed(false);
399 } else {
400 // Touch up when we never crossed the touch slop threshold should
401 // be interpreted as a tap-seek to that location.
402 onStartTrackingTouch();
403 trackTouchEvent(event);
404 onStopTrackingTouch();
405 }
Daniel Sandlereb9fdc22009-09-14 13:05:43 -0400406 // ProgressBar doesn't know to repaint the thumb drawable
407 // in its inactive state when the touch stops (because the
408 // value has not apparently changed)
409 invalidate();
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700410 break;
411
412 case MotionEvent.ACTION_CANCEL:
Adam Powell10298662011-08-14 18:26:30 -0700413 if (mIsDragging) {
414 onStopTrackingTouch();
415 setPressed(false);
416 }
Daniel Sandlereb9fdc22009-09-14 13:05:43 -0400417 invalidate(); // see above explanation
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700418 break;
419 }
420 return true;
421 }
422
423 private void trackTouchEvent(MotionEvent event) {
424 final int width = getWidth();
425 final int available = width - mPaddingLeft - mPaddingRight;
426 int x = (int)event.getX();
427 float scale;
428 float progress = 0;
Fabrice Di Meglio2b378cd2013-01-30 16:39:33 -0800429 if (isLayoutRtl() && mMirrorForRtl) {
Fabrice Di Meglio0af4b8b2012-06-11 18:30:05 -0700430 if (x > width - mPaddingRight) {
431 scale = 0.0f;
432 } else if (x < mPaddingLeft) {
433 scale = 1.0f;
434 } else {
435 scale = (float)(available - x + mPaddingLeft) / (float)available;
436 progress = mTouchProgressOffset;
437 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700438 } else {
Fabrice Di Meglio0af4b8b2012-06-11 18:30:05 -0700439 if (x < mPaddingLeft) {
440 scale = 0.0f;
441 } else if (x > width - mPaddingRight) {
442 scale = 1.0f;
443 } else {
444 scale = (float)(x - mPaddingLeft) / (float)available;
445 progress = mTouchProgressOffset;
446 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700447 }
Jean-Baptiste Queru69577ae2009-03-09 17:56:44 -0700448 final int max = getMax();
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700449 progress += scale * max;
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700450
451 setProgress((int) progress, true);
452 }
The Android Open Source Projectf013e1a2008-12-17 18:05:43 -0800453
454 /**
455 * Tries to claim the user's drag motion, and requests disallowing any
456 * ancestors from stealing events in the drag.
457 */
458 private void attemptClaimDrag() {
459 if (mParent != null) {
460 mParent.requestDisallowInterceptTouchEvent(true);
461 }
462 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700463
464 /**
465 * This is called when the user has started touching this widget.
466 */
467 void onStartTrackingTouch() {
Adam Powell10298662011-08-14 18:26:30 -0700468 mIsDragging = true;
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700469 }
470
471 /**
472 * This is called when the user either releases his touch or the touch is
473 * canceled.
474 */
475 void onStopTrackingTouch() {
Adam Powell10298662011-08-14 18:26:30 -0700476 mIsDragging = false;
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700477 }
478
The Android Open Source Project10592532009-03-18 17:39:46 -0700479 /**
480 * Called when the user changes the seekbar's progress by using a key event.
481 */
482 void onKeyChange() {
483 }
484
The Android Open Source Projectb7986892009-01-09 17:51:23 -0800485 @Override
486 public boolean onKeyDown(int keyCode, KeyEvent event) {
Romain Guy992cc422010-01-04 15:39:40 -0800487 if (isEnabled()) {
488 int progress = getProgress();
489 switch (keyCode) {
490 case KeyEvent.KEYCODE_DPAD_LEFT:
491 if (progress <= 0) break;
492 setProgress(progress - mKeyProgressIncrement, true);
493 onKeyChange();
494 return true;
495
496 case KeyEvent.KEYCODE_DPAD_RIGHT:
497 if (progress >= getMax()) break;
498 setProgress(progress + mKeyProgressIncrement, true);
499 onKeyChange();
500 return true;
501 }
The Android Open Source Projectb7986892009-01-09 17:51:23 -0800502 }
503
504 return super.onKeyDown(keyCode, event);
505 }
506
Svetoslav Ganov8a78fd42012-01-17 14:36:46 -0800507 @Override
508 public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
509 super.onInitializeAccessibilityEvent(event);
510 event.setClassName(AbsSeekBar.class.getName());
511 }
512
513 @Override
514 public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
515 super.onInitializeAccessibilityNodeInfo(info);
516 info.setClassName(AbsSeekBar.class.getName());
alanvc826b7d2012-05-16 14:19:21 -0700517
518 if (isEnabled()) {
519 final int progress = getProgress();
520 if (progress > 0) {
521 info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
522 }
523 if (progress < getMax()) {
524 info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
525 }
526 }
527 }
528
529 @Override
530 public boolean performAccessibilityAction(int action, Bundle arguments) {
531 if (super.performAccessibilityAction(action, arguments)) {
532 return true;
533 }
534 if (!isEnabled()) {
535 return false;
536 }
537 final int progress = getProgress();
538 final int increment = Math.max(1, Math.round((float) getMax() / 5));
539 switch (action) {
540 case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
541 if (progress <= 0) {
542 return false;
543 }
544 setProgress(progress - increment, true);
545 onKeyChange();
546 return true;
547 }
548 case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: {
549 if (progress >= getMax()) {
550 return false;
551 }
552 setProgress(progress + increment, true);
553 onKeyChange();
554 return true;
555 }
556 }
557 return false;
Svetoslav Ganov8a78fd42012-01-17 14:36:46 -0800558 }
Fabrice Di Megliof37df1b2012-10-15 19:10:08 -0700559
560 @Override
561 public void onRtlPropertiesChanged(int layoutDirection) {
562 super.onRtlPropertiesChanged(layoutDirection);
563
564 int max = getMax();
565 float scale = max > 0 ? (float) getProgress() / (float) max : 0;
566
567 Drawable thumb = mThumb;
568 if (thumb != null) {
569 setThumbPos(getWidth(), thumb, scale, Integer.MIN_VALUE);
570 /*
571 * Since we draw translated, the drawable's bounds that it signals
572 * for invalidation won't be the actual bounds we want invalidated,
573 * so just invalidate this whole view.
574 */
575 invalidate();
576 }
577 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700578}