blob: 941cdd0e06914c3a2ea100d43414d2a687870807 [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
Alan Viverette617feb92013-09-09 18:09:13 -070068 public AbsSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
69 this(context, attrs, defStyleAttr, 0);
70 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070071
Alan Viverette617feb92013-09-09 18:09:13 -070072 public AbsSeekBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
73 super(context, attrs, defStyleAttr, defStyleRes);
74
75 TypedArray a = context.obtainStyledAttributes(
76 attrs, com.android.internal.R.styleable.SeekBar, defStyleAttr, defStyleRes);
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070077 Drawable thumb = a.getDrawable(com.android.internal.R.styleable.SeekBar_thumb);
Daniel Sandler8d28c3b2009-08-20 13:34:02 -040078 setThumb(thumb); // will guess mThumbOffset if thumb != null...
79 // ...but allow layout to override this
Romain Guy992cc422010-01-04 15:39:40 -080080 int thumbOffset = a.getDimensionPixelOffset(
81 com.android.internal.R.styleable.SeekBar_thumbOffset, getThumbOffset());
82 setThumbOffset(thumbOffset);
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070083 a.recycle();
84
85 a = context.obtainStyledAttributes(attrs,
86 com.android.internal.R.styleable.Theme, 0, 0);
87 mDisabledAlpha = a.getFloat(com.android.internal.R.styleable.Theme_disabledAlpha, 0.5f);
88 a.recycle();
Adam Powell10298662011-08-14 18:26:30 -070089
90 mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070091 }
92
93 /**
Daniel Sandler8d28c3b2009-08-20 13:34:02 -040094 * Sets the thumb that will be drawn at the end of the progress meter within the SeekBar.
95 * <p>
96 * If the thumb is a valid drawable (i.e. not null), half its width will be
97 * used as the new thumb offset (@see #setThumbOffset(int)).
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070098 *
99 * @param thumb Drawable representing the thumb
100 */
101 public void setThumb(Drawable thumb) {
Joe Onorato2e585f72010-12-02 14:10:57 -0800102 boolean needUpdate;
103 // This way, calling setThumb again with the same bitmap will result in
104 // it recalcuating mThumbOffset (if for example it the bounds of the
105 // drawable changed)
106 if (mThumb != null && thumb != mThumb) {
107 mThumb.setCallback(null);
108 needUpdate = true;
109 } else {
110 needUpdate = false;
111 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700112 if (thumb != null) {
113 thumb.setCallback(this);
Fabrice Di Meglio0af4b8b2012-06-11 18:30:05 -0700114 if (canResolveLayoutDirection()) {
Fabrice Di Meglioe56ffdc2012-09-23 14:51:16 -0700115 thumb.setLayoutDirection(getLayoutDirection());
Fabrice Di Meglio0af4b8b2012-06-11 18:30:05 -0700116 }
Daniel Sandler8d28c3b2009-08-20 13:34:02 -0400117
118 // Assuming the thumb drawable is symmetric, set the thumb offset
119 // such that the thumb will hang halfway off either edge of the
120 // progress bar.
Romain Guy992cc422010-01-04 15:39:40 -0800121 mThumbOffset = thumb.getIntrinsicWidth() / 2;
Joe Onorato2e585f72010-12-02 14:10:57 -0800122
123 // If we're updating get the new states
124 if (needUpdate &&
125 (thumb.getIntrinsicWidth() != mThumb.getIntrinsicWidth()
126 || thumb.getIntrinsicHeight() != mThumb.getIntrinsicHeight())) {
127 requestLayout();
128 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700129 }
130 mThumb = thumb;
131 invalidate();
Joe Onorato2e585f72010-12-02 14:10:57 -0800132 if (needUpdate) {
133 updateThumbPos(getWidth(), getHeight());
Adam Powell0283a552012-04-19 09:58:22 -0700134 if (thumb != null && thumb.isStateful()) {
Joe Onorato2e585f72010-12-02 14:10:57 -0800135 // Note that if the states are different this won't work.
136 // For now, let's consider that an app bug.
137 int[] state = getDrawableState();
138 thumb.setState(state);
139 }
140 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700141 }
142
143 /**
Adam Powell3004cc52012-03-21 17:50:51 -0700144 * Return the drawable used to represent the scroll thumb - the component that
145 * the user can drag back and forth indicating the current value by its position.
146 *
147 * @return The current thumb drawable
148 */
149 public Drawable getThumb() {
150 return mThumb;
151 }
152
153 /**
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700154 * @see #setThumbOffset(int)
155 */
156 public int getThumbOffset() {
157 return mThumbOffset;
158 }
159
160 /**
161 * Sets the thumb offset that allows the thumb to extend out of the range of
162 * the track.
163 *
164 * @param thumbOffset The offset amount in pixels.
165 */
166 public void setThumbOffset(int thumbOffset) {
167 mThumbOffset = thumbOffset;
168 invalidate();
169 }
170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 /**
172 * Sets the amount of progress changed via the arrow keys.
173 *
174 * @param increment The amount to increment or decrement when the user
175 * presses the arrow keys.
176 */
177 public void setKeyProgressIncrement(int increment) {
178 mKeyProgressIncrement = increment < 0 ? -increment : increment;
179 }
180
181 /**
182 * Returns the amount of progress changed via the arrow keys.
183 * <p>
184 * By default, this will be a value that is derived from the max progress.
185 *
186 * @return The amount to increment or decrement when the user presses the
187 * arrow keys. This will be positive.
188 */
189 public int getKeyProgressIncrement() {
190 return mKeyProgressIncrement;
191 }
192
193 @Override
194 public synchronized void setMax(int max) {
195 super.setMax(max);
196
197 if ((mKeyProgressIncrement == 0) || (getMax() / mKeyProgressIncrement > 20)) {
198 // It will take the user too long to change this via keys, change it
199 // to something more reasonable
200 setKeyProgressIncrement(Math.max(1, Math.round((float) getMax() / 20)));
201 }
202 }
203
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700204 @Override
205 protected boolean verifyDrawable(Drawable who) {
206 return who == mThumb || super.verifyDrawable(who);
207 }
208
209 @Override
Dianne Hackborne2136772010-11-04 15:08:59 -0700210 public void jumpDrawablesToCurrentState() {
211 super.jumpDrawablesToCurrentState();
212 if (mThumb != null) mThumb.jumpToCurrentState();
213 }
214
215 @Override
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700216 protected void drawableStateChanged() {
217 super.drawableStateChanged();
218
219 Drawable progressDrawable = getProgressDrawable();
220 if (progressDrawable != null) {
221 progressDrawable.setAlpha(isEnabled() ? NO_ALPHA : (int) (NO_ALPHA * mDisabledAlpha));
222 }
The Android Open Source Projectb7986892009-01-09 17:51:23 -0800223
224 if (mThumb != null && mThumb.isStateful()) {
225 int[] state = getDrawableState();
226 mThumb.setState(state);
227 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700228 }
229
230 @Override
Svetoslav Ganov6518ad72011-03-18 16:19:55 -0700231 void onProgressRefresh(float scale, boolean fromUser) {
232 super.onProgressRefresh(scale, fromUser);
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700233 Drawable thumb = mThumb;
234 if (thumb != null) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700235 setThumbPos(getWidth(), thumb, scale, Integer.MIN_VALUE);
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700236 /*
237 * Since we draw translated, the drawable's bounds that it signals
238 * for invalidation won't be the actual bounds we want invalidated,
239 * so just invalidate this whole view.
240 */
241 invalidate();
242 }
243 }
244
245
246 @Override
247 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Fabrice Di Megliof37df1b2012-10-15 19:10:08 -0700248 super.onSizeChanged(w, h, oldw, oldh);
Joe Onorato2e585f72010-12-02 14:10:57 -0800249 updateThumbPos(w, h);
250 }
251
252 private void updateThumbPos(int w, int h) {
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700253 Drawable d = getCurrentDrawable();
254 Drawable thumb = mThumb;
255 int thumbHeight = thumb == null ? 0 : thumb.getIntrinsicHeight();
256 // The max height does not incorporate padding, whereas the height
257 // parameter does
258 int trackHeight = Math.min(mMaxHeight, h - mPaddingTop - mPaddingBottom);
259
260 int max = getMax();
261 float scale = max > 0 ? (float) getProgress() / (float) max : 0;
262
263 if (thumbHeight > trackHeight) {
264 if (thumb != null) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700265 setThumbPos(w, thumb, scale, 0);
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700266 }
267 int gapForCenteringTrack = (thumbHeight - trackHeight) / 2;
268 if (d != null) {
269 // Canvas will be translated by the padding, so 0,0 is where we start drawing
270 d.setBounds(0, gapForCenteringTrack,
271 w - mPaddingRight - mPaddingLeft, h - mPaddingBottom - gapForCenteringTrack
272 - mPaddingTop);
273 }
274 } else {
275 if (d != null) {
276 // Canvas will be translated by the padding, so 0,0 is where we start drawing
277 d.setBounds(0, 0, w - mPaddingRight - mPaddingLeft, h - mPaddingBottom
278 - mPaddingTop);
279 }
280 int gap = (trackHeight - thumbHeight) / 2;
281 if (thumb != null) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700282 setThumbPos(w, thumb, scale, gap);
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700283 }
284 }
285 }
286
287 /**
288 * @param gap If set to {@link Integer#MIN_VALUE}, this will be ignored and
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700289 */
The Android Open Source Project10592532009-03-18 17:39:46 -0700290 private void setThumbPos(int w, Drawable thumb, float scale, int gap) {
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700291 int available = w - mPaddingLeft - mPaddingRight;
292 int thumbWidth = thumb.getIntrinsicWidth();
293 int thumbHeight = thumb.getIntrinsicHeight();
294 available -= thumbWidth;
295
296 // The extra space for the thumb to move on the track
297 available += mThumbOffset * 2;
298
299 int thumbPos = (int) (scale * available);
300
301 int topBound, bottomBound;
302 if (gap == Integer.MIN_VALUE) {
303 Rect oldBounds = thumb.getBounds();
304 topBound = oldBounds.top;
305 bottomBound = oldBounds.bottom;
306 } else {
307 topBound = gap;
308 bottomBound = gap + thumbHeight;
309 }
310
311 // Canvas will be translated, so 0,0 is where we start drawing
Fabrice Di Meglio2b378cd2013-01-30 16:39:33 -0800312 final int left = (isLayoutRtl() && mMirrorForRtl) ? available - thumbPos : thumbPos;
Fabrice Di Meglio06849e82012-09-11 19:35:06 -0700313 thumb.setBounds(left, topBound, left + thumbWidth, bottomBound);
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700314 }
Fabrice Di Meglio0af4b8b2012-06-11 18:30:05 -0700315
Fabrice Di Meglio4457e852012-09-18 19:23:12 -0700316 /**
317 * @hide
318 */
Fabrice Di Meglio0af4b8b2012-06-11 18:30:05 -0700319 @Override
320 public void onResolveDrawables(int layoutDirection) {
321 super.onResolveDrawables(layoutDirection);
322
323 if (mThumb != null) {
324 mThumb.setLayoutDirection(layoutDirection);
325 }
326 }
327
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700328 @Override
329 protected synchronized void onDraw(Canvas canvas) {
330 super.onDraw(canvas);
331 if (mThumb != null) {
332 canvas.save();
333 // Translate the padding. For the x, we need to allow the thumb to
334 // draw in its extra space
335 canvas.translate(mPaddingLeft - mThumbOffset, mPaddingTop);
336 mThumb.draw(canvas);
337 canvas.restore();
338 }
339 }
340
341 @Override
342 protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
343 Drawable d = getCurrentDrawable();
344
345 int thumbHeight = mThumb == null ? 0 : mThumb.getIntrinsicHeight();
346 int dw = 0;
347 int dh = 0;
348 if (d != null) {
349 dw = Math.max(mMinWidth, Math.min(mMaxWidth, d.getIntrinsicWidth()));
350 dh = Math.max(mMinHeight, Math.min(mMaxHeight, d.getIntrinsicHeight()));
351 dh = Math.max(thumbHeight, dh);
352 }
353 dw += mPaddingLeft + mPaddingRight;
354 dh += mPaddingTop + mPaddingBottom;
355
Dianne Hackborn189ee182010-12-02 21:48:53 -0800356 setMeasuredDimension(resolveSizeAndState(dw, widthMeasureSpec, 0),
357 resolveSizeAndState(dh, heightMeasureSpec, 0));
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700358 }
359
360 @Override
361 public boolean onTouchEvent(MotionEvent event) {
362 if (!mIsUserSeekable || !isEnabled()) {
363 return false;
364 }
365
366 switch (event.getAction()) {
367 case MotionEvent.ACTION_DOWN:
Adam Powell10298662011-08-14 18:26:30 -0700368 if (isInScrollingContainer()) {
369 mTouchDownX = event.getX();
370 } else {
371 setPressed(true);
Adam Powell2c5b8cc2011-10-13 11:44:38 -0700372 if (mThumb != null) {
373 invalidate(mThumb.getBounds()); // This may be within the padding region
374 }
Adam Powell10298662011-08-14 18:26:30 -0700375 onStartTrackingTouch();
376 trackTouchEvent(event);
377 attemptClaimDrag();
378 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700379 break;
380
381 case MotionEvent.ACTION_MOVE:
Adam Powell10298662011-08-14 18:26:30 -0700382 if (mIsDragging) {
383 trackTouchEvent(event);
384 } else {
385 final float x = event.getX();
386 if (Math.abs(x - mTouchDownX) > mScaledTouchSlop) {
387 setPressed(true);
Adam Powell2c5b8cc2011-10-13 11:44:38 -0700388 if (mThumb != null) {
389 invalidate(mThumb.getBounds()); // This may be within the padding region
390 }
Adam Powell10298662011-08-14 18:26:30 -0700391 onStartTrackingTouch();
392 trackTouchEvent(event);
393 attemptClaimDrag();
394 }
395 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700396 break;
397
398 case MotionEvent.ACTION_UP:
Adam Powell10298662011-08-14 18:26:30 -0700399 if (mIsDragging) {
400 trackTouchEvent(event);
401 onStopTrackingTouch();
402 setPressed(false);
403 } else {
404 // Touch up when we never crossed the touch slop threshold should
405 // be interpreted as a tap-seek to that location.
406 onStartTrackingTouch();
407 trackTouchEvent(event);
408 onStopTrackingTouch();
409 }
Daniel Sandlereb9fdc22009-09-14 13:05:43 -0400410 // ProgressBar doesn't know to repaint the thumb drawable
411 // in its inactive state when the touch stops (because the
412 // value has not apparently changed)
413 invalidate();
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700414 break;
415
416 case MotionEvent.ACTION_CANCEL:
Adam Powell10298662011-08-14 18:26:30 -0700417 if (mIsDragging) {
418 onStopTrackingTouch();
419 setPressed(false);
420 }
Daniel Sandlereb9fdc22009-09-14 13:05:43 -0400421 invalidate(); // see above explanation
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700422 break;
423 }
424 return true;
425 }
426
427 private void trackTouchEvent(MotionEvent event) {
428 final int width = getWidth();
429 final int available = width - mPaddingLeft - mPaddingRight;
430 int x = (int)event.getX();
431 float scale;
432 float progress = 0;
Fabrice Di Meglio2b378cd2013-01-30 16:39:33 -0800433 if (isLayoutRtl() && mMirrorForRtl) {
Fabrice Di Meglio0af4b8b2012-06-11 18:30:05 -0700434 if (x > width - mPaddingRight) {
435 scale = 0.0f;
436 } else if (x < mPaddingLeft) {
437 scale = 1.0f;
438 } else {
439 scale = (float)(available - x + mPaddingLeft) / (float)available;
440 progress = mTouchProgressOffset;
441 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700442 } else {
Fabrice Di Meglio0af4b8b2012-06-11 18:30:05 -0700443 if (x < mPaddingLeft) {
444 scale = 0.0f;
445 } else if (x > width - mPaddingRight) {
446 scale = 1.0f;
447 } else {
448 scale = (float)(x - mPaddingLeft) / (float)available;
449 progress = mTouchProgressOffset;
450 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700451 }
Jean-Baptiste Queru69577ae2009-03-09 17:56:44 -0700452 final int max = getMax();
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700453 progress += scale * max;
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700454
455 setProgress((int) progress, true);
456 }
The Android Open Source Projectf013e1a2008-12-17 18:05:43 -0800457
458 /**
459 * Tries to claim the user's drag motion, and requests disallowing any
460 * ancestors from stealing events in the drag.
461 */
462 private void attemptClaimDrag() {
463 if (mParent != null) {
464 mParent.requestDisallowInterceptTouchEvent(true);
465 }
466 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700467
468 /**
469 * This is called when the user has started touching this widget.
470 */
471 void onStartTrackingTouch() {
Adam Powell10298662011-08-14 18:26:30 -0700472 mIsDragging = true;
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700473 }
474
475 /**
476 * This is called when the user either releases his touch or the touch is
477 * canceled.
478 */
479 void onStopTrackingTouch() {
Adam Powell10298662011-08-14 18:26:30 -0700480 mIsDragging = false;
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700481 }
482
The Android Open Source Project10592532009-03-18 17:39:46 -0700483 /**
484 * Called when the user changes the seekbar's progress by using a key event.
485 */
486 void onKeyChange() {
487 }
488
The Android Open Source Projectb7986892009-01-09 17:51:23 -0800489 @Override
490 public boolean onKeyDown(int keyCode, KeyEvent event) {
Romain Guy992cc422010-01-04 15:39:40 -0800491 if (isEnabled()) {
492 int progress = getProgress();
493 switch (keyCode) {
494 case KeyEvent.KEYCODE_DPAD_LEFT:
495 if (progress <= 0) break;
496 setProgress(progress - mKeyProgressIncrement, true);
497 onKeyChange();
498 return true;
499
500 case KeyEvent.KEYCODE_DPAD_RIGHT:
501 if (progress >= getMax()) break;
502 setProgress(progress + mKeyProgressIncrement, true);
503 onKeyChange();
504 return true;
505 }
The Android Open Source Projectb7986892009-01-09 17:51:23 -0800506 }
507
508 return super.onKeyDown(keyCode, event);
509 }
510
Svetoslav Ganov8a78fd42012-01-17 14:36:46 -0800511 @Override
512 public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
513 super.onInitializeAccessibilityEvent(event);
514 event.setClassName(AbsSeekBar.class.getName());
515 }
516
517 @Override
518 public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
519 super.onInitializeAccessibilityNodeInfo(info);
520 info.setClassName(AbsSeekBar.class.getName());
alanvc826b7d2012-05-16 14:19:21 -0700521
522 if (isEnabled()) {
523 final int progress = getProgress();
524 if (progress > 0) {
525 info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
526 }
527 if (progress < getMax()) {
528 info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
529 }
530 }
531 }
532
533 @Override
534 public boolean performAccessibilityAction(int action, Bundle arguments) {
535 if (super.performAccessibilityAction(action, arguments)) {
536 return true;
537 }
538 if (!isEnabled()) {
539 return false;
540 }
541 final int progress = getProgress();
542 final int increment = Math.max(1, Math.round((float) getMax() / 5));
543 switch (action) {
544 case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
545 if (progress <= 0) {
546 return false;
547 }
548 setProgress(progress - increment, true);
549 onKeyChange();
550 return true;
551 }
552 case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: {
553 if (progress >= getMax()) {
554 return false;
555 }
556 setProgress(progress + increment, true);
557 onKeyChange();
558 return true;
559 }
560 }
561 return false;
Svetoslav Ganov8a78fd42012-01-17 14:36:46 -0800562 }
Fabrice Di Megliof37df1b2012-10-15 19:10:08 -0700563
564 @Override
565 public void onRtlPropertiesChanged(int layoutDirection) {
566 super.onRtlPropertiesChanged(layoutDirection);
567
568 int max = getMax();
569 float scale = max > 0 ? (float) getProgress() / (float) max : 0;
570
571 Drawable thumb = mThumb;
572 if (thumb != null) {
573 setThumbPos(getWidth(), thumb, scale, Integer.MIN_VALUE);
574 /*
575 * Since we draw translated, the drawable's bounds that it signals
576 * for invalidation won't be the actual bounds we want invalidated,
577 * so just invalidate this whole view.
578 */
579 invalidate();
580 }
581 }
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -0700582}