Java tutorial
/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.support.v17.leanback.widget; import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; import android.os.Bundle; import android.support.annotation.RestrictTo; import android.support.v17.leanback.R; import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; import android.util.AttributeSet; import android.view.View; /** * Replacement of SeekBar, has two bar heights and two thumb size when focused/not_focused. * The widget does not deal with KeyEvent, it's client's responsibility to set a key listener. * @hide */ @RestrictTo(LIBRARY_GROUP) public final class SeekBar extends View { /** * @hide */ @RestrictTo(LIBRARY_GROUP) public abstract static class AccessibilitySeekListener { /** * Called to perform AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD */ public abstract boolean onAccessibilitySeekForward(); /** * Called to perform AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD */ public abstract boolean onAccessibilitySeekBackward(); } private final RectF mProgressRect = new RectF(); private final RectF mSecondProgressRect = new RectF(); private final RectF mBackgroundRect = new RectF(); private final Paint mSecondProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final Paint mProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final Paint mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final Paint mKnobPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private int mProgress; private int mSecondProgress; private int mMax; private int mKnobx; private int mActiveRadius; private int mBarHeight; private int mActiveBarHeight; private AccessibilitySeekListener mAccessibilitySeekListener; public SeekBar(Context context, AttributeSet attrs) { super(context, attrs); setWillNotDraw(false); mBackgroundPaint.setColor(Color.GRAY); mSecondProgressPaint.setColor(Color.LTGRAY); mProgressPaint.setColor(Color.RED); mKnobPaint.setColor(Color.WHITE); mBarHeight = context.getResources() .getDimensionPixelSize(R.dimen.lb_playback_transport_progressbar_bar_height); mActiveBarHeight = context.getResources() .getDimensionPixelSize(R.dimen.lb_playback_transport_progressbar_active_bar_height); mActiveRadius = context.getResources() .getDimensionPixelSize(R.dimen.lb_playback_transport_progressbar_active_radius); } /** * Set radius in pixels for thumb when SeekBar is focused. */ public void setActiveRadius(int radius) { mActiveRadius = radius; calculate(); } /** * Set horizontal bar height in pixels when SeekBar is not focused. */ public void setBarHeight(int barHeight) { mBarHeight = barHeight; calculate(); } /** * Set horizontal bar height in pixels when SeekBar is focused. */ public void setActiveBarHeight(int activeBarHeight) { mActiveBarHeight = activeBarHeight; calculate(); } @Override protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) { super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); calculate(); } @Override protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh) { super.onSizeChanged(w, h, oldw, oldh); calculate(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); final int radius = isFocused() ? mActiveRadius : mBarHeight / 2; canvas.drawRoundRect(mBackgroundRect, radius, radius, mBackgroundPaint); canvas.drawRoundRect(mSecondProgressRect, radius, radius, mProgressPaint); canvas.drawRoundRect(mProgressRect, radius, radius, mProgressPaint); canvas.drawCircle(mKnobx, getHeight() / 2, radius, mKnobPaint); } /** * Set progress within 0 and {@link #getMax()} */ public void setProgress(int progress) { if (progress > mMax) { progress = mMax; } else if (progress < 0) { progress = 0; } mProgress = progress; calculate(); } /** * Set secondary progress within 0 and {@link #getMax()} */ public void setSecondaryProgress(int progress) { if (progress > mMax) { progress = mMax; } else if (progress < 0) { progress = 0; } mSecondProgress = progress; calculate(); } /** * Get progress within 0 and {@link #getMax()} */ public int getProgress() { return mProgress; } /** * Get secondary progress within 0 and {@link #getMax()} */ public int getSecondProgress() { return mSecondProgress; } /** * Get max value. */ public int getMax() { return mMax; } /** * Set max value. */ public void setMax(int max) { this.mMax = max; calculate(); } /** * Set color for progress. */ public void setProgressColor(int color) { mProgressPaint.setColor(color); } private void calculate() { final int barHeight = isFocused() ? mActiveBarHeight : mBarHeight; final int width = getWidth(); final int height = getHeight(); final int verticalPadding = (height - barHeight) / 2; mBackgroundRect.set(mBarHeight / 2, verticalPadding, width - mBarHeight / 2, height - verticalPadding); final int radius = isFocused() ? mActiveRadius : mBarHeight / 2; final int progressWidth = width - radius * 2; final float progressPixels = mProgress / (float) mMax * progressWidth; mProgressRect.set(mBarHeight / 2, verticalPadding, mBarHeight / 2 + progressPixels, height - verticalPadding); final float secondProgressPixels = mSecondProgress / (float) mMax * progressWidth; mSecondProgressRect.set(mBarHeight / 2, verticalPadding, mBarHeight / 2 + secondProgressPixels, height - verticalPadding); mKnobx = radius + (int) progressPixels; invalidate(); } @Override public CharSequence getAccessibilityClassName() { return android.widget.SeekBar.class.getName(); } public void setAccessibilitySeekListener(AccessibilitySeekListener listener) { mAccessibilitySeekListener = listener; } @Override public boolean performAccessibilityAction(int action, Bundle arguments) { if (mAccessibilitySeekListener != null) { switch (action) { case AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD: return mAccessibilitySeekListener.onAccessibilitySeekForward(); case AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD: return mAccessibilitySeekListener.onAccessibilitySeekBackward(); } } return super.performAccessibilityAction(action, arguments); } }