package com.tws.app.myapplication.view;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import com.tws.app.myapplication.R;
public class SliderBar extends View {
? ? //畫(huà)背景的Paint
? ? private Paint mBgPaint;
? ? //畫(huà)進(jìn)度條的Paint
? ? private Paint mProgressPaint;
? ? //開(kāi)始位置
? ? private int mStart;
? ? private int mProEnd;
? ? private int mWidth;
? ? private int mHeight;
? ? //結(jié)束位置
? ? private int mEnd;
? ? //漸變顏色 三個(gè)
? ? private int mStartColor;
? ? private int mEndColor;
? ? //背景顏色
? ? private int mBgColor;
? ? //當(dāng)前進(jìn)度
? ? private float mProgress;
? ? //小圓點(diǎn)半徑
? ? private int mRadius;
? ? //顯示文字的Rect
? ? private Rect mTxtRec;
? ? //最里面白色圓的半徑
? ? private int mMinRadio;
? ? //線中心距離上方距離
? ? private int mTop;
? ? //文字距離線的距離
? ? private int mTextTop;
? ? private float mMaxSun;
? ? private float mMinSun;
? ? private Paint mSunPaint;
? ? private Canvas mLeftSunCanvas = new Canvas();
? ? private Canvas mLeftTopSunCanvas = new Canvas();
? ? private Canvas mLeftDownSunCanvas = new Canvas();
? ? private Canvas mTopSunCanvas = new Canvas();
? ? private Canvas mRightTopSunCanvas = new Canvas();
? ? private Canvas mRightSunCanvas = new Canvas();
? ? private Canvas mRightDownCanvas = new Canvas();
? ? private Canvas mDownCanvas = new Canvas();
? ? //進(jìn)度條改變回調(diào)
? ? private ProgressChange progressChange;
? ? private LinearGradient mLinearGradient;
? ? public SliderBar(Context context) {
? ? ? ? this(context, null);
? ? }
? ? public SliderBar(Context context, @Nullable AttributeSet attrs) {
? ? ? ? this(context, attrs, 0);
? ? }
? ? public SliderBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
? ? ? ? this(context, attrs, defStyleAttr, 0);
? ? }
? ? public SliderBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
? ? ? ? super(context, attrs, defStyleAttr, defStyleRes);
? ? ? ? initPaint();
? ? ? ? initParams(context, attrs, defStyleAttr);
? ? }
? ? private void initPaint() {
? ? ? ? mBgPaint = new Paint();
? ? ? ? mBgPaint.setAntiAlias(true);
? ? ? ? mBgPaint.setStrokeCap(Paint.Cap.SQUARE);
? ? ? ? mProgressPaint = new Paint();
? ? ? ? mProgressPaint.setAntiAlias(true);
? ? ? ? mProgressPaint.setStrokeCap(Paint.Cap.ROUND);
? ? ? ? mSunPaint = new Paint();
? ? ? ? mSunPaint.setAntiAlias(true);
? ? ? ? mSunPaint.setStrokeCap(Paint.Cap.ROUND);
? ? ? ? mSunPaint.setStrokeWidth(8);
? ? }
? ? /***
? ? * 初始化公共參數(shù)
? ? */
? ? public void initParams(Context context, AttributeSet attrs, int defStyleAttr) {
? ? ? ? TypedArray seekArray = context.obtainStyledAttributes(attrs, R.styleable.SliderBar, defStyleAttr, 0);
? ? ? ? mStartColor = seekArray.getColor(R.styleable.SliderBar_startColor, ContextCompat.getColor(context, R.color.startColor));
? ? ? ? mEndColor = seekArray.getColor(R.styleable.SliderBar_endColor, ContextCompat.getColor(context, R.color.endColor));
? ? ? ? mBgColor = seekArray.getColor(R.styleable.SliderBar_bgColor, ContextCompat.getColor(context, R.color.bgColor));
? ? ? ? mRadius = (int) seekArray.getDimension(R.styleable.SliderBar_radius, dp2px(8));
? ? ? ? mMinRadio = (int) seekArray.getDimension(R.styleable.SliderBar_minRadio, dp2px(40));
? ? ? ? mTxtRec = new Rect();
? ? ? ? mMaxSun = (float) (mRadius * 0.6f / 1.7);
? ? ? ? mMinSun = (float) (mRadius * 0.4f / 1.7);
? ? ? ? mSunPaint.setColor(ContextCompat.getColor(context, R.color.white));
? ? ? ? seekArray.recycle();
? ? }
? ? private float dp2px(int input) {
? ? ? ? float scale = Resources.getSystem().getDisplayMetrics().density;
? ? ? ? return (float) ((input / scale) + 0.5);
? ? }
? ? @Override
? ? protected void onSizeChanged(int w, int h, int oldw, int oldh) {
? ? ? ? super.onSizeChanged(w, h, oldw, oldh);
? ? ? ? //初始化高和寬
? ? ? ? initWidthAndHeight(w, h);
? ? }
? ? protected void initWidthAndHeight(int w, int h) {
? ? ? ? mStart = getPaddingStart();
? ? ? ? mTop = getPaddingTop();
? ? ? ? mEnd = getMeasuredWidth() - getPaddingRight();
? ? ? ? mWidth = mEnd - mStart;
? ? ? ? mHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
? ? ? ? mLinearGradient = new LinearGradient(0, 0, w, h
? ? ? ? ? ? ? ? , new int[]{mStartColor, mEndColor}
? ? ? ? ? ? ? ? , new float[]{0, 1F}
? ? ? ? ? ? ? ? , Shader.TileMode.CLAMP);
? ? ? ? mBgPaint.setStrokeWidth((float) mHeight);
? ? ? ? mProgressPaint.setStrokeWidth((float) mHeight);
? ? }
? ? public interface ProgressChange {
? ? ? ? void onProgressChange(float progress);
? ? }
? ? @Override
? ? protected void onDraw(Canvas canvas) {
? ? ? ? super.onDraw(canvas);
? ? ? ? drawBg(canvas);
? ? ? ? drawProgress(canvas);
? ? ? ? drawSun(canvas);
? ? }
? ? /**
? ? * set progres
? ? *
? ? * @param mProgress progress
? ? */
? ? public void setProgress(float mProgress) {
? ? ? ? this.mProgress = mProgress;
? ? ? ? invalidate();
? ? }
? ? private void drawBg(Canvas canvas) {
? ? ? ? mBgPaint.setColor(mBgColor);
? ? ? ? canvas.drawRoundRect(mStart + 1, mTop, mEnd - 1, mHeight, mRadius, mRadius, mBgPaint);
? ? }
? ? private void drawProgress(Canvas canvas) {
? ? ? ? mProgressPaint.setShader(mLinearGradient);
? ? ? ? mProEnd = (int) ((mProgress) * (mEnd - mStart)) + mStart;
? ? ? ? if (mProEnd <= mRadius * 2) {
? ? ? ? ? ? mProEnd = mRadius * 2;
? ? ? ? }
? ? ? ? canvas.drawRoundRect(mStart, mTop, mProEnd, mHeight, mRadius, mRadius, mProgressPaint);
? ? }
? ? private void drawSun(Canvas canvas) {
? ? ? ? float scale = mProgress * (mMaxSun - mMinSun) + mMinSun;
? ? ? ? int alpha = (int) (255 * (mProgress * 0.2f + 0.8f));
? ? ? ? canvas.drawCircle((mStart + mRadius), (mStart + mRadius), scale, mSunPaint);
? ? ? ? float lightLength = scale * 0.3F;
? ? ? ? float lightOffset = scale * 1.7F;
? ? ? ? float mLightStartX = mStart + mRadius;
? ? ? ? int mLightStartY = mTop + mRadius;
? ? ? ? canvas.save();
? ? ? ? for (int i = 0; i < 8; i++) {
? ? ? ? ? ? float radians = (float) Math.toRadians(i * 45);
? ? ? ? ? ? float offsetX = (float) (lightOffset * Math.cos(radians));
? ? ? ? ? ? float offsetY = (float) (lightOffset * Math.sin(radians));
? ? ? ? ? ? float x1, x2, y1, y2;
? ? ? ? ? ? x1 = mLightStartX + offsetX;
? ? ? ? ? ? x2 = (float) (x1 + lightLength * Math.cos(radians));
? ? ? ? ? ? y1 = mLightStartY + offsetY;
? ? ? ? ? ? y2 = (float) (y1 + lightLength * Math.sin(radians));
? ? ? ? ? ? mSunPaint.setAlpha(alpha);
? ? ? ? ? ? canvas.drawLine(x1, y1, x2, y2, mSunPaint);
? ? ? ? }
? ? }
? ? @Override
? ? public boolean onTouchEvent(MotionEvent event) {
? ? ? ? switch (event.getActionMasked()) {
? ? ? ? ? ? case MotionEvent.ACTION_DOWN:
? ? ? ? ? ? case MotionEvent.ACTION_MOVE:
? ? ? ? ? ? ? ? getProgress(event);
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case MotionEvent.ACTION_UP:
? ? ? ? ? ? case MotionEvent.ACTION_CANCEL:
? ? ? ? ? ? ? ? getRootView().performClick();
? ? ? ? ? ? ? ? invalidate();
? ? ? ? ? ? ? ? break;
? ? ? ? }
? ? ? ? return true;
? ? }
? ? /***
? ? * 計(jì)算進(jìn)度
? ? */
? ? private void getProgress(MotionEvent event) {
? ? ? ? mProgress = event.getX() / (mWidth - mRadius);
? ? ? ? if (mProgress < 0) {
? ? ? ? ? ? mProgress = 0;
? ? ? ? }
? ? ? ? if (mProgress > 1) {
? ? ? ? ? ? mProgress = 1;
? ? ? ? }
? ? ? ? if (progressChange != null) {
? ? ? ? ? ? progressChange.onProgressChange(mProgress);
? ? ? ? }
? ? ? ? invalidate();
? ? }
? ? /**
? ? * set progress listener
? ? *
? ? * @param progressChange progress listener
? ? */
? ? public void setProgressChange(ProgressChange progressChange) {
? ? ? ? this.progressChange = progressChange;
? ? }
}