AbsSeekBar.java revision 1029866a12e04e9db52485e2ec0353e764d15549
154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project/*
254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project *
454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * you may not use this file except in compliance with the License.
654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * You may obtain a copy of the License at
754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project *
854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project *
1054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * See the License for the specific language governing permissions and
1454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project * limitations under the License.
1554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project */
1654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
1754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectpackage android.widget;
1854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
1954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.content.Context;
2054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.content.res.TypedArray;
2154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.Canvas;
2254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.Rect;
2354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.graphics.drawable.Drawable;
2454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.util.AttributeSet;
25b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Projectimport android.view.KeyEvent;
2654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectimport android.view.MotionEvent;
271029866a12e04e9db52485e2ec0353e764d15549Adam Powellimport android.view.ViewConfiguration;
2854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
2954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectpublic abstract class AbsSeekBar extends ProgressBar {
3054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    private Drawable mThumb;
3154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    private int mThumbOffset;
3254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
3354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    /**
3454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     * On touch, this offset plus the scaled value from the position of the
3554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     * touch will form the progress value. Usually 0.
3654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     */
3754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    float mTouchProgressOffset;
3854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
3954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    /**
4054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     * Whether this is user seekable.
4154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     */
4254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    boolean mIsUserSeekable = true;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * On key presses (right or left), the amount to increment/decrement the
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * progress.
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mKeyProgressIncrement = 1;
4954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
5054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    private static final int NO_ALPHA = 0xFF;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private float mDisabledAlpha;
5254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
531029866a12e04e9db52485e2ec0353e764d15549Adam Powell    private int mScaledTouchSlop;
541029866a12e04e9db52485e2ec0353e764d15549Adam Powell    private float mTouchDownX;
551029866a12e04e9db52485e2ec0353e764d15549Adam Powell    private boolean mIsDragging;
561029866a12e04e9db52485e2ec0353e764d15549Adam Powell
5754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public AbsSeekBar(Context context) {
5854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super(context);
5954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
6054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
6154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public AbsSeekBar(Context context, AttributeSet attrs) {
6254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super(context, attrs);
6354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
6454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
6554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public AbsSeekBar(Context context, AttributeSet attrs, int defStyle) {
6654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super(context, attrs, defStyle);
6754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
6854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        TypedArray a = context.obtainStyledAttributes(attrs,
6954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                com.android.internal.R.styleable.SeekBar, defStyle, 0);
7054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        Drawable thumb = a.getDrawable(com.android.internal.R.styleable.SeekBar_thumb);
718d28c3b3bdab63fab132b81e38d54bc4c132ea8aDaniel Sandler        setThumb(thumb); // will guess mThumbOffset if thumb != null...
728d28c3b3bdab63fab132b81e38d54bc4c132ea8aDaniel Sandler        // ...but allow layout to override this
73992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy        int thumbOffset = a.getDimensionPixelOffset(
74992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy                com.android.internal.R.styleable.SeekBar_thumbOffset, getThumbOffset());
75992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy        setThumbOffset(thumbOffset);
7654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        a.recycle();
7754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
7854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        a = context.obtainStyledAttributes(attrs,
7954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                com.android.internal.R.styleable.Theme, 0, 0);
8054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mDisabledAlpha = a.getFloat(com.android.internal.R.styleable.Theme_disabledAlpha, 0.5f);
8154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        a.recycle();
821029866a12e04e9db52485e2ec0353e764d15549Adam Powell
831029866a12e04e9db52485e2ec0353e764d15549Adam Powell        mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
8454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
8554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
8654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    /**
878d28c3b3bdab63fab132b81e38d54bc4c132ea8aDaniel Sandler     * Sets the thumb that will be drawn at the end of the progress meter within the SeekBar.
888d28c3b3bdab63fab132b81e38d54bc4c132ea8aDaniel Sandler     * <p>
898d28c3b3bdab63fab132b81e38d54bc4c132ea8aDaniel Sandler     * If the thumb is a valid drawable (i.e. not null), half its width will be
908d28c3b3bdab63fab132b81e38d54bc4c132ea8aDaniel Sandler     * used as the new thumb offset (@see #setThumbOffset(int)).
9154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     *
9254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     * @param thumb Drawable representing the thumb
9354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     */
9454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public void setThumb(Drawable thumb) {
952e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato        boolean needUpdate;
962e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato        // This way, calling setThumb again with the same bitmap will result in
972e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato        // it recalcuating mThumbOffset (if for example it the bounds of the
982e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato        // drawable changed)
992e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato        if (mThumb != null && thumb != mThumb) {
1002e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato            mThumb.setCallback(null);
1012e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato            needUpdate = true;
1022e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato        } else {
1032e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato            needUpdate = false;
1042e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato        }
10554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (thumb != null) {
10654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            thumb.setCallback(this);
1078d28c3b3bdab63fab132b81e38d54bc4c132ea8aDaniel Sandler
1088d28c3b3bdab63fab132b81e38d54bc4c132ea8aDaniel Sandler            // Assuming the thumb drawable is symmetric, set the thumb offset
1098d28c3b3bdab63fab132b81e38d54bc4c132ea8aDaniel Sandler            // such that the thumb will hang halfway off either edge of the
1108d28c3b3bdab63fab132b81e38d54bc4c132ea8aDaniel Sandler            // progress bar.
111992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy            mThumbOffset = thumb.getIntrinsicWidth() / 2;
1122e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato
1132e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato            // If we're updating get the new states
1142e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato            if (needUpdate &&
1152e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato                    (thumb.getIntrinsicWidth() != mThumb.getIntrinsicWidth()
1162e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato                        || thumb.getIntrinsicHeight() != mThumb.getIntrinsicHeight())) {
1172e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato                requestLayout();
1182e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato            }
11954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
12054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mThumb = thumb;
12154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        invalidate();
1222e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato        if (needUpdate) {
1232e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato            updateThumbPos(getWidth(), getHeight());
1242e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato            if (thumb.isStateful()) {
1252e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato                // Note that if the states are different this won't work.
1262e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato                // For now, let's consider that an app bug.
1272e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato                int[] state = getDrawableState();
1282e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato                thumb.setState(state);
1292e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato            }
1302e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato        }
13154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
13254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
13354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    /**
13454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     * @see #setThumbOffset(int)
13554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     */
13654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public int getThumbOffset() {
13754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return mThumbOffset;
13854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
13954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
14054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    /**
14154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     * Sets the thumb offset that allows the thumb to extend out of the range of
14254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     * the track.
14354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     *
14454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     * @param thumbOffset The offset amount in pixels.
14554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     */
14654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public void setThumbOffset(int thumbOffset) {
14754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        mThumbOffset = thumbOffset;
14854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        invalidate();
14954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
15054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets the amount of progress changed via the arrow keys.
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param increment The amount to increment or decrement when the user
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *            presses the arrow keys.
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setKeyProgressIncrement(int increment) {
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mKeyProgressIncrement = increment < 0 ? -increment : increment;
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the amount of progress changed via the arrow keys.
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * By default, this will be a value that is derived from the max progress.
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return The amount to increment or decrement when the user presses the
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *         arrow keys. This will be positive.
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getKeyProgressIncrement() {
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mKeyProgressIncrement;
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public synchronized void setMax(int max) {
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.setMax(max);
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((mKeyProgressIncrement == 0) || (getMax() / mKeyProgressIncrement > 20)) {
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // It will take the user too long to change this via keys, change it
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // to something more reasonable
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setKeyProgressIncrement(Math.max(1, Math.round((float) getMax() / 20)));
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
18554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    protected boolean verifyDrawable(Drawable who) {
18654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return who == mThumb || super.verifyDrawable(who);
18754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
18854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
18954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
190e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn    public void jumpDrawablesToCurrentState() {
191e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn        super.jumpDrawablesToCurrentState();
192e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn        if (mThumb != null) mThumb.jumpToCurrentState();
193e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn    }
194e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn
195e213677037f836529efcc0ac201fc61dd95481c5Dianne Hackborn    @Override
19654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    protected void drawableStateChanged() {
19754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super.drawableStateChanged();
19854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
19954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        Drawable progressDrawable = getProgressDrawable();
20054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (progressDrawable != null) {
20154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            progressDrawable.setAlpha(isEnabled() ? NO_ALPHA : (int) (NO_ALPHA * mDisabledAlpha));
20254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
203b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project
204b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project        if (mThumb != null && mThumb.isStateful()) {
205b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project            int[] state = getDrawableState();
206b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project            mThumb.setState(state);
207b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project        }
20854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
20954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
21054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
2116518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov    void onProgressRefresh(float scale, boolean fromUser) {
2126518ad760f98a0aa5db8c49ce1564bf5907a2c15Svetoslav Ganov        super.onProgressRefresh(scale, fromUser);
21354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        Drawable thumb = mThumb;
21454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (thumb != null) {
215105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            setThumbPos(getWidth(), thumb, scale, Integer.MIN_VALUE);
21654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            /*
21754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project             * Since we draw translated, the drawable's bounds that it signals
21854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project             * for invalidation won't be the actual bounds we want invalidated,
21954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project             * so just invalidate this whole view.
22054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project             */
22154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            invalidate();
22254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
22354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
22454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
22554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
22654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
22754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
2282e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato        updateThumbPos(w, h);
2292e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato    }
2302e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato
2312e585f7e22efef11dc6af36acfbf1c3040d6a511Joe Onorato    private void updateThumbPos(int w, int h) {
23254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        Drawable d = getCurrentDrawable();
23354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        Drawable thumb = mThumb;
23454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int thumbHeight = thumb == null ? 0 : thumb.getIntrinsicHeight();
23554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // The max height does not incorporate padding, whereas the height
23654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // parameter does
23754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int trackHeight = Math.min(mMaxHeight, h - mPaddingTop - mPaddingBottom);
23854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
23954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int max = getMax();
24054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        float scale = max > 0 ? (float) getProgress() / (float) max : 0;
24154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
24254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (thumbHeight > trackHeight) {
24354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (thumb != null) {
244105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                setThumbPos(w, thumb, scale, 0);
24554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
24654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            int gapForCenteringTrack = (thumbHeight - trackHeight) / 2;
24754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (d != null) {
24854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                // Canvas will be translated by the padding, so 0,0 is where we start drawing
24954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                d.setBounds(0, gapForCenteringTrack,
25054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        w - mPaddingRight - mPaddingLeft, h - mPaddingBottom - gapForCenteringTrack
25154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        - mPaddingTop);
25254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
25354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        } else {
25454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (d != null) {
25554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                // Canvas will be translated by the padding, so 0,0 is where we start drawing
25654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                d.setBounds(0, 0, w - mPaddingRight - mPaddingLeft, h - mPaddingBottom
25754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        - mPaddingTop);
25854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
25954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            int gap = (trackHeight - thumbHeight) / 2;
26054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (thumb != null) {
261105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                setThumbPos(w, thumb, scale, gap);
26254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
26354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
26454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
26554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
26654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    /**
26754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     * @param gap If set to {@link Integer#MIN_VALUE}, this will be ignored and
26854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     */
269105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    private void setThumbPos(int w, Drawable thumb, float scale, int gap) {
27054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int available = w - mPaddingLeft - mPaddingRight;
27154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int thumbWidth = thumb.getIntrinsicWidth();
27254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int thumbHeight = thumb.getIntrinsicHeight();
27354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        available -= thumbWidth;
27454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
27554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // The extra space for the thumb to move on the track
27654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        available += mThumbOffset * 2;
27754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
27854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int thumbPos = (int) (scale * available);
27954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
28054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int topBound, bottomBound;
28154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (gap == Integer.MIN_VALUE) {
28254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            Rect oldBounds = thumb.getBounds();
28354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            topBound = oldBounds.top;
28454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            bottomBound = oldBounds.bottom;
28554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        } else {
28654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            topBound = gap;
28754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            bottomBound = gap + thumbHeight;
28854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
28954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
29054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // Canvas will be translated, so 0,0 is where we start drawing
29154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        thumb.setBounds(thumbPos, topBound, thumbPos + thumbWidth, bottomBound);
29254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
29354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
29454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
29554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    protected synchronized void onDraw(Canvas canvas) {
29654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        super.onDraw(canvas);
29754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (mThumb != null) {
29854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            canvas.save();
29954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // Translate the padding. For the x, we need to allow the thumb to
30054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // draw in its extra space
30154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            canvas.translate(mPaddingLeft - mThumbOffset, mPaddingTop);
30254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            mThumb.draw(canvas);
30354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            canvas.restore();
30454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
30554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
30654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
30754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
30854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
30954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        Drawable d = getCurrentDrawable();
31054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
31154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int thumbHeight = mThumb == null ? 0 : mThumb.getIntrinsicHeight();
31254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int dw = 0;
31354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int dh = 0;
31454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (d != null) {
31554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            dw = Math.max(mMinWidth, Math.min(mMaxWidth, d.getIntrinsicWidth()));
31654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            dh = Math.max(mMinHeight, Math.min(mMaxHeight, d.getIntrinsicHeight()));
31754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            dh = Math.max(thumbHeight, dh);
31854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
31954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        dw += mPaddingLeft + mPaddingRight;
32054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        dh += mPaddingTop + mPaddingBottom;
32154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
322189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn        setMeasuredDimension(resolveSizeAndState(dw, widthMeasureSpec, 0),
323189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn                resolveSizeAndState(dh, heightMeasureSpec, 0));
32454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
32554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
32654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    @Override
32754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    public boolean onTouchEvent(MotionEvent event) {
32854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (!mIsUserSeekable || !isEnabled()) {
32954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return false;
33054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
33154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
33254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        switch (event.getAction()) {
33354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            case MotionEvent.ACTION_DOWN:
3341029866a12e04e9db52485e2ec0353e764d15549Adam Powell                if (isInScrollingContainer()) {
3351029866a12e04e9db52485e2ec0353e764d15549Adam Powell                    mTouchDownX = event.getX();
3361029866a12e04e9db52485e2ec0353e764d15549Adam Powell                } else {
3371029866a12e04e9db52485e2ec0353e764d15549Adam Powell                    setPressed(true);
3381029866a12e04e9db52485e2ec0353e764d15549Adam Powell                    onStartTrackingTouch();
3391029866a12e04e9db52485e2ec0353e764d15549Adam Powell                    trackTouchEvent(event);
3401029866a12e04e9db52485e2ec0353e764d15549Adam Powell                    attemptClaimDrag();
3411029866a12e04e9db52485e2ec0353e764d15549Adam Powell                }
34254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                break;
34354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
34454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            case MotionEvent.ACTION_MOVE:
3451029866a12e04e9db52485e2ec0353e764d15549Adam Powell                if (mIsDragging) {
3461029866a12e04e9db52485e2ec0353e764d15549Adam Powell                    trackTouchEvent(event);
3471029866a12e04e9db52485e2ec0353e764d15549Adam Powell                } else {
3481029866a12e04e9db52485e2ec0353e764d15549Adam Powell                    final float x = event.getX();
3491029866a12e04e9db52485e2ec0353e764d15549Adam Powell                    if (Math.abs(x - mTouchDownX) > mScaledTouchSlop) {
3501029866a12e04e9db52485e2ec0353e764d15549Adam Powell                        setPressed(true);
3511029866a12e04e9db52485e2ec0353e764d15549Adam Powell                        onStartTrackingTouch();
3521029866a12e04e9db52485e2ec0353e764d15549Adam Powell                        trackTouchEvent(event);
3531029866a12e04e9db52485e2ec0353e764d15549Adam Powell                        attemptClaimDrag();
3541029866a12e04e9db52485e2ec0353e764d15549Adam Powell                    }
3551029866a12e04e9db52485e2ec0353e764d15549Adam Powell                }
35654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                break;
35754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
35854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            case MotionEvent.ACTION_UP:
3591029866a12e04e9db52485e2ec0353e764d15549Adam Powell                if (mIsDragging) {
3601029866a12e04e9db52485e2ec0353e764d15549Adam Powell                    trackTouchEvent(event);
3611029866a12e04e9db52485e2ec0353e764d15549Adam Powell                    onStopTrackingTouch();
3621029866a12e04e9db52485e2ec0353e764d15549Adam Powell                    setPressed(false);
3631029866a12e04e9db52485e2ec0353e764d15549Adam Powell                } else {
3641029866a12e04e9db52485e2ec0353e764d15549Adam Powell                    // Touch up when we never crossed the touch slop threshold should
3651029866a12e04e9db52485e2ec0353e764d15549Adam Powell                    // be interpreted as a tap-seek to that location.
3661029866a12e04e9db52485e2ec0353e764d15549Adam Powell                    onStartTrackingTouch();
3671029866a12e04e9db52485e2ec0353e764d15549Adam Powell                    trackTouchEvent(event);
3681029866a12e04e9db52485e2ec0353e764d15549Adam Powell                    onStopTrackingTouch();
3691029866a12e04e9db52485e2ec0353e764d15549Adam Powell                }
370eb9fdc21b14368b2f8c71939eb063ddcee8c28a2Daniel Sandler                // ProgressBar doesn't know to repaint the thumb drawable
371eb9fdc21b14368b2f8c71939eb063ddcee8c28a2Daniel Sandler                // in its inactive state when the touch stops (because the
372eb9fdc21b14368b2f8c71939eb063ddcee8c28a2Daniel Sandler                // value has not apparently changed)
373eb9fdc21b14368b2f8c71939eb063ddcee8c28a2Daniel Sandler                invalidate();
37454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                break;
37554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
37654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            case MotionEvent.ACTION_CANCEL:
3771029866a12e04e9db52485e2ec0353e764d15549Adam Powell                if (mIsDragging) {
3781029866a12e04e9db52485e2ec0353e764d15549Adam Powell                    onStopTrackingTouch();
3791029866a12e04e9db52485e2ec0353e764d15549Adam Powell                    setPressed(false);
3801029866a12e04e9db52485e2ec0353e764d15549Adam Powell                }
381eb9fdc21b14368b2f8c71939eb063ddcee8c28a2Daniel Sandler                invalidate(); // see above explanation
38254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                break;
38354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
38454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        return true;
38554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
38654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
38754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    private void trackTouchEvent(MotionEvent event) {
38854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        final int width = getWidth();
38954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        final int available = width - mPaddingLeft - mPaddingRight;
39054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int x = (int)event.getX();
39154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        float scale;
39254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        float progress = 0;
39354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (x < mPaddingLeft) {
39454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            scale = 0.0f;
39554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        } else if (x > width - mPaddingRight) {
39654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            scale = 1.0f;
39754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        } else {
39854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            scale = (float)(x - mPaddingLeft) / (float)available;
39954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            progress = mTouchProgressOffset;
40054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
40154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
40269577ae794751e6ecaca6a580b1b33545bd21082Jean-Baptiste Queru        final int max = getMax();
40354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        progress += scale * max;
40454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
40554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        setProgress((int) progress, true);
40654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
407f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project
408f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    /**
409f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project     * Tries to claim the user's drag motion, and requests disallowing any
410f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project     * ancestors from stealing events in the drag.
411f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project     */
412f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    private void attemptClaimDrag() {
413f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project        if (mParent != null) {
414f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project            mParent.requestDisallowInterceptTouchEvent(true);
415f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project        }
416f013e1afd1e68af5e3b868c26a653bbfb39538f8The Android Open Source Project    }
41754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
41854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    /**
41954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     * This is called when the user has started touching this widget.
42054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     */
42154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    void onStartTrackingTouch() {
4221029866a12e04e9db52485e2ec0353e764d15549Adam Powell        mIsDragging = true;
42354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
42454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
42554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    /**
42654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     * This is called when the user either releases his touch or the touch is
42754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     * canceled.
42854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     */
42954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    void onStopTrackingTouch() {
4301029866a12e04e9db52485e2ec0353e764d15549Adam Powell        mIsDragging = false;
43154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
43254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
433105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    /**
434105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * Called when the user changes the seekbar's progress by using a key event.
435105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     */
436105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    void onKeyChange() {
437105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
438105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
439b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project    @Override
440b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project    public boolean onKeyDown(int keyCode, KeyEvent event) {
441992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy        if (isEnabled()) {
442992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy            int progress = getProgress();
443992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy            switch (keyCode) {
444992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy                case KeyEvent.KEYCODE_DPAD_LEFT:
445992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy                    if (progress <= 0) break;
446992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy                    setProgress(progress - mKeyProgressIncrement, true);
447992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy                    onKeyChange();
448992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy                    return true;
449992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy
450992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy                case KeyEvent.KEYCODE_DPAD_RIGHT:
451992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy                    if (progress >= getMax()) break;
452992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy                    setProgress(progress + mKeyProgressIncrement, true);
453992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy                    onKeyChange();
454992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy                    return true;
455992cc4282e92c0b7c192247261c54933acab5ad0Romain Guy            }
456b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project        }
457b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project
458b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project        return super.onKeyDown(keyCode, event);
459b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project    }
460b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project
46154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
462