@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); int thumbWidth = mThumb.getIntrinsicWidth(); int thumbHeight = mThumb.getIntrinsicHeight(); int addedThumb = mAddedTouchBounds; int halfThumb = thumbWidth / 2; int paddingLeft = getPaddingLeft() + addedThumb; int paddingRight = getPaddingRight(); int bottom = getHeight() - getPaddingBottom() - addedThumb; mThumb.setBounds(paddingLeft, bottom - thumbHeight, paddingLeft + thumbWidth, bottom); int trackHeight = Math.max(mTrackHeight / 2, 1); mTrack.setBounds( paddingLeft + halfThumb, bottom - halfThumb - trackHeight, getWidth() - halfThumb - paddingRight - addedThumb, bottom - halfThumb + trackHeight); int scrubberHeight = Math.max(mScrubberHeight / 2, 2); mScrubber.setBounds( paddingLeft + halfThumb, bottom - halfThumb - scrubberHeight, paddingLeft + halfThumb, bottom - halfThumb + scrubberHeight); // Update the thumb position after size changed updateThumbPosFromCurrentProgress(); }
private void updateThumbPos(int posX) { int thumbWidth = mThumb.getIntrinsicWidth(); int halfThumb = thumbWidth / 2; int start; if (isRtl()) { start = getWidth() - getPaddingRight() - mAddedTouchBounds; posX = start - posX - thumbWidth; } else { start = getPaddingLeft() + mAddedTouchBounds; posX = start + posX; } mThumb.copyBounds(mInvalidateRect); mThumb.setBounds(posX, mInvalidateRect.top, posX + thumbWidth, mInvalidateRect.bottom); if (isRtl()) { mScrubber.getBounds().right = start - halfThumb; mScrubber.getBounds().left = posX + halfThumb; } else { mScrubber.getBounds().left = start + halfThumb; mScrubber.getBounds().right = posX + halfThumb; } final Rect finalBounds = mTempRect; mThumb.copyBounds(finalBounds); if (!isInEditMode()) { mIndicator.move(finalBounds.centerX()); } mInvalidateRect.inset(-mAddedTouchBounds, -mAddedTouchBounds); finalBounds.inset(-mAddedTouchBounds, -mAddedTouchBounds); mInvalidateRect.union(finalBounds); SeekBarCompat.setHotspotBounds( mRipple, finalBounds.left, finalBounds.top, finalBounds.right, finalBounds.bottom); invalidate(mInvalidateRect); }
@Override protected synchronized void onDraw(Canvas canvas) { if (!isLollipopOrGreater) { mRipple.draw(canvas); } super.onDraw(canvas); mTrack.draw(canvas); mScrubber.draw(canvas); mThumb.draw(canvas); }
private void updateFromDrawableState() { int[] state = getDrawableState(); boolean focused = false; boolean pressed = false; for (int i : state) { if (i == FOCUSED_STATE) { focused = true; } else if (i == PRESSED_STATE) { pressed = true; } } if (isEnabled() && (focused || pressed) && mIndicatorPopupEnabled) { // We want to add a small delay here to avoid // poping in/out on simple taps removeCallbacks(mShowIndicatorRunnable); postDelayed(mShowIndicatorRunnable, INDICATOR_DELAY_FOR_TAPS); } else { hideFloater(); } mThumb.setState(state); mTrack.setState(state); mScrubber.setState(state); mRipple.setState(state); }
/** * Sets the color of the seekbar scrubber * * @param colorStateList The ColorStateList the track will be changed to */ public void setTrackColor(@NonNull ColorStateList colorStateList) { mTrack.setColorStateList(colorStateList); }
/** * Sets the color of the seekbar scrubber * * @param color The color the track will be changed to */ public void setTrackColor(int color) { mTrack.setColorStateList(ColorStateList.valueOf(color)); }
/** * Sets the color of the seekbar scrubber * * @param colorStateList The ColorStateList the track scrubber will be changed to */ public void setScrubberColor(@NonNull ColorStateList colorStateList) { mScrubber.setColorStateList(colorStateList); }
/** * Sets the color of the seekbar scrubber * * @param color The color the track scrubber will be changed to */ public void setScrubberColor(int color) { mScrubber.setColorStateList(ColorStateList.valueOf(color)); }
public DiscreteSeekBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setFocusable(true); setWillNotDraw(false); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); float density = context.getResources().getDisplayMetrics().density; mTrackHeight = (int) (1 * density); mScrubberHeight = (int) (4 * density); int thumbSize = (int) (density * ThumbDrawable.DEFAULT_SIZE_DP); // Extra pixels for a touch area of 48dp int touchBounds = (int) (density * 32); mAddedTouchBounds = (touchBounds - thumbSize) / 2; TypedArray a = context.obtainStyledAttributes( attrs, R.styleable.DiscreteSeekBar, defStyleAttr, R.style.Widget_DiscreteSeekBar); int max = 100; int min = 0; int value = 0; mMirrorForRtl = a.getBoolean(R.styleable.DiscreteSeekBar_dsb_mirrorForRtl, mMirrorForRtl); mAllowTrackClick = a.getBoolean(R.styleable.DiscreteSeekBar_dsb_allowTrackClickToDrag, mAllowTrackClick); mIndicatorPopupEnabled = a.getBoolean(R.styleable.DiscreteSeekBar_dsb_indicatorPopupEnabled, mIndicatorPopupEnabled); int indexMax = R.styleable.DiscreteSeekBar_dsb_max; int indexMin = R.styleable.DiscreteSeekBar_dsb_min; int indexValue = R.styleable.DiscreteSeekBar_dsb_value; final TypedValue out = new TypedValue(); // Not sure why, but we wanted to be able to use dimensions here... if (a.getValue(indexMax, out)) { if (out.type == TypedValue.TYPE_DIMENSION) { max = a.getDimensionPixelSize(indexMax, max); } else { max = a.getInteger(indexMax, max); } } if (a.getValue(indexMin, out)) { if (out.type == TypedValue.TYPE_DIMENSION) { min = a.getDimensionPixelSize(indexMin, min); } else { min = a.getInteger(indexMin, min); } } if (a.getValue(indexValue, out)) { if (out.type == TypedValue.TYPE_DIMENSION) { value = a.getDimensionPixelSize(indexValue, value); } else { value = a.getInteger(indexValue, value); } } mMin = min; mMax = Math.max(min + 1, max); mValue = Math.max(min, Math.min(max, value)); updateKeyboardRange(); mIndicatorFormatter = a.getString(R.styleable.DiscreteSeekBar_dsb_indicatorFormatter); ColorStateList trackColor = a.getColorStateList(R.styleable.DiscreteSeekBar_dsb_trackColor); ColorStateList progressColor = a.getColorStateList(R.styleable.DiscreteSeekBar_dsb_progressColor); ColorStateList rippleColor = a.getColorStateList(R.styleable.DiscreteSeekBar_dsb_rippleColor); boolean editMode = isInEditMode(); if (editMode || rippleColor == null) { rippleColor = new ColorStateList(new int[][] {new int[] {}}, new int[] {Color.DKGRAY}); } if (editMode || trackColor == null) { trackColor = new ColorStateList(new int[][] {new int[] {}}, new int[] {Color.GRAY}); } if (editMode || progressColor == null) { progressColor = new ColorStateList(new int[][] {new int[] {}}, new int[] {DEFAULT_THUMB_COLOR}); } mRipple = SeekBarCompat.getRipple(rippleColor); if (isLollipopOrGreater) { SeekBarCompat.setBackground(this, mRipple); } else { mRipple.setCallback(this); } TrackRectDrawable shapeDrawable = new TrackRectDrawable(trackColor); mTrack = shapeDrawable; mTrack.setCallback(this); shapeDrawable = new TrackRectDrawable(progressColor); mScrubber = shapeDrawable; mScrubber.setCallback(this); mThumb = new ThumbDrawable(progressColor, thumbSize); mThumb.setCallback(this); mThumb.setBounds(0, 0, mThumb.getIntrinsicWidth(), mThumb.getIntrinsicHeight()); if (!editMode) { mIndicator = new PopupIndicator(context, attrs, defStyleAttr, convertValueToMessage(mMax)); mIndicator.setListener(mFloaterListener); } a.recycle(); setNumericTransformer(new DefaultNumericTransformer()); }