1f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen/* 2f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Copyright (C) 2007 The Android Open Source Project 3f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 4f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Licensed under the Apache License, Version 2.0 (the "License"); 5f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * you may not use this file except in compliance with the License. 6f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * You may obtain a copy of the License at 7f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 8f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * http://www.apache.org/licenses/LICENSE-2.0 9f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 10f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Unless required by applicable law or agreed to in writing, software 11f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * distributed under the License is distributed on an "AS IS" BASIS, 12f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * See the License for the specific language governing permissions and 14f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * limitations under the License. 15f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 16f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 17f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenpackage com.android.musicfx.seekbar; 18f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 19f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.content.Context; 20f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.content.res.TypedArray; 21f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.graphics.Canvas; 22f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.graphics.Rect; 23f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.graphics.drawable.Drawable; 24f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.util.AttributeSet; 25f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.view.KeyEvent; 26f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenimport android.view.MotionEvent; 27f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 28f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissenpublic abstract class AbsSeekBar extends ProgressBar { 29f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private Drawable mThumb; 30f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private int mThumbOffset; 31f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 32f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 33f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * On touch, this offset plus the scaled value from the position of the 34f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * touch will form the progress value. Usually 0. 35f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 36f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen float mTouchProgressOffset; 37f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 38f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 39f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Whether this is user seekable. 40f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 41f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen boolean mIsUserSeekable = true; 42f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 432deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen boolean mIsVertical = false; 44f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 45f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * On key presses (right or left), the amount to increment/decrement the 46f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * progress. 47f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 48f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private int mKeyProgressIncrement = 1; 49f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 50f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private static final int NO_ALPHA = 0xFF; 51f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private float mDisabledAlpha; 52f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 53f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public AbsSeekBar(Context context) { 54f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super(context); 55f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 56f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 57f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public AbsSeekBar(Context context, AttributeSet attrs) { 58f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super(context, attrs); 59f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 60f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 61f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public AbsSeekBar(Context context, AttributeSet attrs, int defStyle) { 62f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super(context, attrs, defStyle); 63f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 64f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen TypedArray a = context.obtainStyledAttributes(attrs, 65f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen com.android.internal.R.styleable.SeekBar, defStyle, 0); 66f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen Drawable thumb = a.getDrawable(com.android.internal.R.styleable.SeekBar_thumb); 67f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setThumb(thumb); // will guess mThumbOffset if thumb != null... 68f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // ...but allow layout to override this 69f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int thumbOffset = a.getDimensionPixelOffset( 70f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen com.android.internal.R.styleable.SeekBar_thumbOffset, getThumbOffset()); 71f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setThumbOffset(thumbOffset); 72f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen a.recycle(); 73f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 74f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen a = context.obtainStyledAttributes(attrs, 75f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen com.android.internal.R.styleable.Theme, 0, 0); 76f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mDisabledAlpha = a.getFloat(com.android.internal.R.styleable.Theme_disabledAlpha, 0.5f); 77f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen a.recycle(); 78f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 79f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 80f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 81f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Sets the thumb that will be drawn at the end of the progress meter within the SeekBar. 82f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p> 83f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * If the thumb is a valid drawable (i.e. not null), half its width will be 84f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * used as the new thumb offset (@see #setThumbOffset(int)). 85f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 86f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @param thumb Drawable representing the thumb 87f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 88f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public void setThumb(Drawable thumb) { 89f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen boolean needUpdate; 90f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // This way, calling setThumb again with the same bitmap will result in 91f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // it recalcuating mThumbOffset (if for example it the bounds of the 92f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // drawable changed) 93f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mThumb != null && thumb != mThumb) { 94f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mThumb.setCallback(null); 95f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen needUpdate = true; 96f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } else { 97f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen needUpdate = false; 98f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 99f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (thumb != null) { 100f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen thumb.setCallback(this); 101f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 102f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // Assuming the thumb drawable is symmetric, set the thumb offset 103f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // such that the thumb will hang halfway off either edge of the 104f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // progress bar. 1052deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (mIsVertical) { 1062deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen mThumbOffset = thumb.getIntrinsicHeight() / 2; 1072deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } else { 1082deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen mThumbOffset = thumb.getIntrinsicWidth() / 2; 1092deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } 110f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 111f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // If we're updating get the new states 112f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (needUpdate && 113f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen (thumb.getIntrinsicWidth() != mThumb.getIntrinsicWidth() 114f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen || thumb.getIntrinsicHeight() != mThumb.getIntrinsicHeight())) { 115f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen requestLayout(); 116f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 117f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 118f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mThumb = thumb; 119f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen invalidate(); 120f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (needUpdate) { 121f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen updateThumbPos(getWidth(), getHeight()); 122f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (thumb.isStateful()) { 123f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // Note that if the states are different this won't work. 124f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // For now, let's consider that an app bug. 125f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int[] state = getDrawableState(); 126f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen thumb.setState(state); 127f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 128f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 129f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 130f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 131f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 132f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @see #setThumbOffset(int) 133f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 134f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public int getThumbOffset() { 135f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return mThumbOffset; 136f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 137f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 138f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 139f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Sets the thumb offset that allows the thumb to extend out of the range of 140f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * the track. 141f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 142f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @param thumbOffset The offset amount in pixels. 143f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 144f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public void setThumbOffset(int thumbOffset) { 145f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mThumbOffset = thumbOffset; 146f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen invalidate(); 147f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 148f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 149f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 150f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Sets the amount of progress changed via the arrow keys. 151f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 152f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @param increment The amount to increment or decrement when the user 153f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * presses the arrow keys. 154f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 155f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public void setKeyProgressIncrement(int increment) { 156f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mKeyProgressIncrement = increment < 0 ? -increment : increment; 157f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 158f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 159f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 160f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Returns the amount of progress changed via the arrow keys. 161f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * <p> 162f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * By default, this will be a value that is derived from the max progress. 163f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * 164f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @return The amount to increment or decrement when the user presses the 165f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * arrow keys. This will be positive. 166f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 167f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public int getKeyProgressIncrement() { 168f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return mKeyProgressIncrement; 169f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 170f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 171f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 172f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public synchronized void setMax(int max) { 173f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super.setMax(max); 174f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 175f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if ((mKeyProgressIncrement == 0) || (getMax() / mKeyProgressIncrement > 20)) { 176f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // It will take the user too long to change this via keys, change it 177f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // to something more reasonable 178f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setKeyProgressIncrement(Math.max(1, Math.round((float) getMax() / 20))); 179f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 180f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 181f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 182f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 183f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen protected boolean verifyDrawable(Drawable who) { 184f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return who == mThumb || super.verifyDrawable(who); 185f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 186f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 187f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 188f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public void jumpDrawablesToCurrentState() { 189f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super.jumpDrawablesToCurrentState(); 190f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mThumb != null) mThumb.jumpToCurrentState(); 191f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 192f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 193f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 194f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen protected void drawableStateChanged() { 195f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super.drawableStateChanged(); 196f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 197f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen Drawable progressDrawable = getProgressDrawable(); 198f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (progressDrawable != null) { 199f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen progressDrawable.setAlpha(isEnabled() ? NO_ALPHA : (int) (NO_ALPHA * mDisabledAlpha)); 200f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 201f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 202f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mThumb != null && mThumb.isStateful()) { 203f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int[] state = getDrawableState(); 204f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mThumb.setState(state); 205f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 206f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 207f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 208f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 209f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen void onProgressRefresh(float scale, boolean fromUser) { 210f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super.onProgressRefresh(scale, fromUser); 211f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen Drawable thumb = mThumb; 212f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (thumb != null) { 2132deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen setThumbPos(getWidth(), getHeight(), thumb, scale, Integer.MIN_VALUE); 214f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /* 215f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Since we draw translated, the drawable's bounds that it signals 216f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * for invalidation won't be the actual bounds we want invalidated, 217f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * so just invalidate this whole view. 218f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 219f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen invalidate(); 220f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 221f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 222f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 223f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 224f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 225f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen protected void onSizeChanged(int w, int h, int oldw, int oldh) { 226f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen updateThumbPos(w, h); 227f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 228f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 229f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private void updateThumbPos(int w, int h) { 230f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen Drawable d = getCurrentDrawable(); 231f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen Drawable thumb = mThumb; 2322deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (mIsVertical) { 2332deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen int thumbWidth = thumb == null ? 0 : thumb.getIntrinsicWidth(); 2342deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen // The max width does not incorporate padding, whereas the width 2352deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen // parameter does 2362deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen int trackWidth = Math.min(mMaxWidth, w - mPaddingLeft - mPaddingRight); 2372deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen 2382deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen int max = getMax(); 2392deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen float scale = max > 0 ? (float) getProgress() / (float) max : 0; 2402deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen 2412deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (thumbWidth > trackWidth) { 2422deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (thumb != null) { 2432deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen setThumbPos(w, h, thumb, scale, 0); 2442deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } 2452deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen int gapForCenteringTrack = (thumbWidth - trackWidth) / 2; 2462deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (d != null) { 2472deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen // Canvas will be translated by the padding, so 0,0 is where we start drawing 2482deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen d.setBounds(gapForCenteringTrack, 0, 2492deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen w - mPaddingRight - gapForCenteringTrack - mPaddingLeft, 2502deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen h - mPaddingBottom - mPaddingTop); 2512deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } 2522deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } else { 2532deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (d != null) { 2542deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen // Canvas will be translated by the padding, so 0,0 is where we start drawing 2552deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen d.setBounds(0, 0, w - mPaddingRight - mPaddingLeft, h - mPaddingBottom 2562deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen - mPaddingTop); 2572deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } 2582deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen int gap = (trackWidth - thumbWidth) / 2; 2592deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (thumb != null) { 2602deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen setThumbPos(w, h, thumb, scale, gap); 2612deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } 262f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 263f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } else { 2642deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen int thumbHeight = thumb == null ? 0 : thumb.getIntrinsicHeight(); 2652deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen // The max height does not incorporate padding, whereas the height 2662deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen // parameter does 2672deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen int trackHeight = Math.min(mMaxHeight, h - mPaddingTop - mPaddingBottom); 2682deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen 2692deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen int max = getMax(); 2702deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen float scale = max > 0 ? (float) getProgress() / (float) max : 0; 2712deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen 2722deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (thumbHeight > trackHeight) { 2732deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (thumb != null) { 2742deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen setThumbPos(w, h, thumb, scale, 0); 2752deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } 2762deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen int gapForCenteringTrack = (thumbHeight - trackHeight) / 2; 2772deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (d != null) { 2782deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen // Canvas will be translated by the padding, so 0,0 is where we start drawing 2792deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen d.setBounds(0, gapForCenteringTrack, 2802deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen w - mPaddingRight - mPaddingLeft, h - mPaddingBottom - gapForCenteringTrack 2812deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen - mPaddingTop); 2822deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } 2832deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } else { 2842deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (d != null) { 2852deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen // Canvas will be translated by the padding, so 0,0 is where we start drawing 2862deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen d.setBounds(0, 0, w - mPaddingRight - mPaddingLeft, h - mPaddingBottom 2872deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen - mPaddingTop); 2882deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } 2892deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen int gap = (trackHeight - thumbHeight) / 2; 2902deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (thumb != null) { 2912deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen setThumbPos(w, h, thumb, scale, gap); 2922deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } 293f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 294f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 295f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 296f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 297f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 298f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * @param gap If set to {@link Integer#MIN_VALUE}, this will be ignored and 299f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 3002deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen private void setThumbPos(int w, int h, Drawable thumb, float scale, int gap) { 3012deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen int available; 302f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int thumbWidth = thumb.getIntrinsicWidth(); 303f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int thumbHeight = thumb.getIntrinsicHeight(); 3042deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (mIsVertical) { 3052deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen available = h - mPaddingTop - mPaddingBottom - thumbHeight; 3062deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } else { 3072deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen available = w - mPaddingLeft - mPaddingRight - thumbWidth; 3082deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } 309f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 310f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // The extra space for the thumb to move on the track 311f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen available += mThumbOffset * 2; 312f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 313f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 3142deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (mIsVertical) { 3152deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen int thumbPos = (int) ((1.0f - scale) * available); 3162deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen int leftBound, rightBound; 3172deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (gap == Integer.MIN_VALUE) { 3182deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen Rect oldBounds = thumb.getBounds(); 3192deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen leftBound = oldBounds.left; 3202deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen rightBound = oldBounds.right; 3212deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } else { 3222deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen leftBound = gap; 3232deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen rightBound = gap + thumbWidth; 3242deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } 3252deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen 3262deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen // Canvas will be translated, so 0,0 is where we start drawing 3272deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen thumb.setBounds(leftBound, thumbPos, rightBound, thumbPos + thumbHeight); 328f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } else { 3292deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen int thumbPos = (int) (scale * available); 3302deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen int topBound, bottomBound; 3312deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (gap == Integer.MIN_VALUE) { 3322deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen Rect oldBounds = thumb.getBounds(); 3332deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen topBound = oldBounds.top; 3342deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen bottomBound = oldBounds.bottom; 3352deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } else { 3362deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen topBound = gap; 3372deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen bottomBound = gap + thumbHeight; 3382deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } 3392deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen 3402deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen // Canvas will be translated, so 0,0 is where we start drawing 3412deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen thumb.setBounds(thumbPos, topBound, thumbPos + thumbWidth, bottomBound); 342f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 343f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 344f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 345f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 346f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen protected synchronized void onDraw(Canvas canvas) { 347f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen super.onDraw(canvas); 348f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mThumb != null) { 349f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen canvas.save(); 3502deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen // Translate the padding. For the x/y, we need to allow the thumb to 351f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // draw in its extra space 3522deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (mIsVertical) { 3532deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen canvas.translate(mPaddingLeft, mPaddingTop - mThumbOffset); 3542deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen mThumb.draw(canvas); 3552deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen canvas.restore(); 3562deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } else { 3572deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen canvas.translate(mPaddingLeft - mThumbOffset, mPaddingTop); 3582deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen mThumb.draw(canvas); 3592deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen canvas.restore(); 3602deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } 361f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 362f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 363f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 364f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 365f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 366f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen Drawable d = getCurrentDrawable(); 367f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 368f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int thumbHeight = mThumb == null ? 0 : mThumb.getIntrinsicHeight(); 369f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int dw = 0; 370f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int dh = 0; 371f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (d != null) { 372f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen dw = Math.max(mMinWidth, Math.min(mMaxWidth, d.getIntrinsicWidth())); 373f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen dh = Math.max(mMinHeight, Math.min(mMaxHeight, d.getIntrinsicHeight())); 374f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen dh = Math.max(thumbHeight, dh); 375f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 376f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen dw += mPaddingLeft + mPaddingRight; 377f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen dh += mPaddingTop + mPaddingBottom; 378f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 379f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setMeasuredDimension(resolveSizeAndState(dw, widthMeasureSpec, 0), 380f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen resolveSizeAndState(dh, heightMeasureSpec, 0)); 3812deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen 3822deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen // TODO should probably make this an explicit attribute instead of implicitly 3832deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen // setting it based on the size 3842deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (getMeasuredHeight() > getMeasuredWidth()) { 3852deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen mIsVertical = true; 3862deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } 387f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 388f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 389f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 390f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public boolean onTouchEvent(MotionEvent event) { 391f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (!mIsUserSeekable || !isEnabled()) { 392f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return false; 393f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 394f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 395f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen switch (event.getAction()) { 396f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen case MotionEvent.ACTION_DOWN: 397f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setPressed(true); 398f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen onStartTrackingTouch(); 399f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen trackTouchEvent(event); 400f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen break; 401f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 402f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen case MotionEvent.ACTION_MOVE: 403f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen trackTouchEvent(event); 404f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen attemptClaimDrag(); 405f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen break; 406f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 407f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen case MotionEvent.ACTION_UP: 408f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen trackTouchEvent(event); 409f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen onStopTrackingTouch(); 410f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setPressed(false); 411f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // ProgressBar doesn't know to repaint the thumb drawable 412f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // in its inactive state when the touch stops (because the 413f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen // value has not apparently changed) 414f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen invalidate(); 415f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen break; 416f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 417f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen case MotionEvent.ACTION_CANCEL: 418f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen onStopTrackingTouch(); 419f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setPressed(false); 420f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen invalidate(); // see above explanation 421f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen break; 422f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 423f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return true; 424f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 425f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 426f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private void trackTouchEvent(MotionEvent event) { 427f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen float progress = 0; 4282deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (mIsVertical) { 4292deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen final int height = getHeight(); 4302deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen final int available = height - mPaddingTop - mPaddingBottom; 4312deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen int y = (int)event.getY(); 4322deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen float scale; 4332deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (y < mPaddingTop) { 4342deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen scale = 1.0f; 4352deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } else if (y > height - mPaddingBottom) { 4362deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen scale = 0.0f; 4372deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } else { 4382deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen scale = 1.0f - (float)(y - mPaddingTop) / (float)available; 4392deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen progress = mTouchProgressOffset; 4402deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } 4412deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen 4422deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen final int max = getMax(); 4432deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen progress += scale * max; 444f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } else { 4452deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen final int width = getWidth(); 4462deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen final int available = width - mPaddingLeft - mPaddingRight; 4472deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen int x = (int)event.getX(); 4482deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen float scale; 4492deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (x < mPaddingLeft) { 4502deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen scale = 0.0f; 4512deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } else if (x > width - mPaddingRight) { 4522deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen scale = 1.0f; 4532deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } else { 4542deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen scale = (float)(x - mPaddingLeft) / (float)available; 4552deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen progress = mTouchProgressOffset; 4562deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } 4572deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen 4582deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen final int max = getMax(); 4592deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen progress += scale * max; 460f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 461f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 462f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setProgress((int) progress, true); 463f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 464f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 465f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 466f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Tries to claim the user's drag motion, and requests disallowing any 467f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * ancestors from stealing events in the drag. 468f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 469f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen private void attemptClaimDrag() { 470f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (mParent != null) { 471f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen mParent.requestDisallowInterceptTouchEvent(true); 472f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 473f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 474f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 475f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 476f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * This is called when the user has started touching this widget. 477f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 478f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen void onStartTrackingTouch() { 479f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 480f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 481f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 482f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * This is called when the user either releases his touch or the touch is 483f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * canceled. 484f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 485f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen void onStopTrackingTouch() { 486f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 487f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 488f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen /** 489f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen * Called when the user changes the seekbar's progress by using a key event. 490f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen */ 491f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen void onKeyChange() { 492f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 493f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 494f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen @Override 495f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen public boolean onKeyDown(int keyCode, KeyEvent event) { 496f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen if (isEnabled()) { 497f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen int progress = getProgress(); 4982deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if ((keyCode == KeyEvent.KEYCODE_DPAD_LEFT && !mIsVertical) 4992deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen || (keyCode == KeyEvent.KEYCODE_DPAD_DOWN && mIsVertical)) { 5002deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (progress > 0) { 501f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setProgress(progress - mKeyProgressIncrement, true); 502f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen onKeyChange(); 503f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return true; 5042deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } 5052deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } else if ((keyCode == KeyEvent.KEYCODE_DPAD_RIGHT && !mIsVertical) 5062deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen || (keyCode == KeyEvent.KEYCODE_DPAD_UP && mIsVertical)) { 5072deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen if (progress < getMax()) { 508f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen setProgress(progress + mKeyProgressIncrement, true); 509f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen onKeyChange(); 510f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return true; 5112deae778cee2b40946bfe08f8702761b77fc223fMarco Nelissen } 512f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 513f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 514f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 515f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen return super.onKeyDown(keyCode, event); 516f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen } 517f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen 518f568b605f08a5d8401e21387bf9c4a83167d1160Marco Nelissen} 519