赞
踩
记录下之前开发ui效果。
public class RoundScaleView2 extends View { private static final String TAG = "RoundScaleView2"; private Context mContext; /** * 画笔对象的引用 */ private Paint paint; /** * 圆环的宽度 */ private float roundWidth; /** * 最大进度 */ private int max; /** * 当前进度 */ private int progress = 0; private int progress2 = 0; private boolean lightType = false; public static final int LIGHTID = 66; private int last_y = -1; private int last_y2 = -1; private int numberOfPointers = 1; String[] paintColors = { "#FF0000", "#FF2525", "#FF9C00", "#FFEF00", "#CBFF00", "#7BFF00", "#00FF37", "#02E863", "#00D35E", "#00C45C", "#00D795", "#00C1FF" ,"#0082FF", "#0050FF", "#0032FF", "#0000FF", "#2814FF", "#4E00FF", "#6A10FF", "#BD0EFF", "#FF00E3", "#FF2288", "#FF1666", "#FF0039" ,"#E60000", "#FF0000", "#FF0000", "#FF0000", "#FF0000", "#FF0000", "#FF0000", "#FF0000", "#FF0000", "#FF0000", "#FF0000", "#FF0000" }; // 调整后颜色值 int[] colors = { 0xFF0000, 0xFF0500, 0xFF5000, 0xC8C800, 0x82FF00, 0x64FF00, 0x46FF00, 0x1EFF00, 0x28C800, 0x146400, 0x14DC05, 0x00A00F ,0x14641E, 0x003232, 0x003296, 0x0032E6, 0x0000FF, 0x1E00FF, 0x3C00FF, 0x6400FF, 0x960064, 0xC8001E, 0xEB000A, 0xFF0005 ,0xE60000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000 }; int[] progress_rate = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ,12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 ,24, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1}; private PointF mProgressPoint; private PointF mProgressPoint2; private Boolean isEnabled = true; public RoundScaleView2(Context context) { this(context, null); } public RoundScaleView2(Context context, AttributeSet attrs) { this(context, attrs, 0); } public RoundScaleView2(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mContext = context; paint = new Paint(); //获取自定义属性和默认值 roundWidth = dip2px(context,9); //最大刻度 max = 36; //外边距 paddingOuterThumb = dip2px(mContext,10); } @Override public void onDraw(Canvas canvas) { /** * 圆环颜色 */ paint.setStrokeWidth(roundWidth); //设置圆环的宽度 paint.setColor(getResources().getColor(R.color.transparent)); //设置进度的颜色 // paint.setColor(getResources().getColor(R.color.light_effectt_red)); RectF oval2 = new RectF(centerX - radius , centerY - radius , centerX + radius , centerY + radius); //用于定义的圆弧的形状和大小的界限 paint.setStyle(Paint.Style.STROKE); paint.setAntiAlias(true); //消除锯齿 canvas.drawArc(oval2, 270, 360, false, paint); //根据进度画圆弧 // 画Thumb canvas.save(); //画可拖动的圆点 if (isLightType()){ drawTouchBar(canvas); } } /** * 画可拖动的圆点 * @param canvas */ private void drawTouchBar(Canvas canvas) { mProgressPoint = calcArcEndPointXY(centerX, centerY, radius + 30, 360 * progress / max, (float) 150.5); // //直接用画笔画 paint.setColor(Color.parseColor(getPaintColors())); canvas.drawCircle(mProgressPoint.x, mProgressPoint.y,1,paint); // canvas.rotate(getTouchBarOffset(),progressPoint.x, progressPoint.y); // canvas.drawRect(progressPoint.x, progressPoint.y,progressPoint.x, progressPoint.y,paint); canvas.restore(); canvas.save(); mProgressPoint2 = calcArcEndPointXY(centerX, centerY, radius + 30, 360 * progress2 / max, (float) 150.5); // //直接用画笔画 paint.setColor(Color.parseColor(getPaintColors2())); canvas.drawCircle(mProgressPoint2.x, mProgressPoint2.y,1,paint); canvas.restore(); } public String getPaintColors() { String color = "#000000"; HashMap<Integer, Object> map = new HashMap<>(); for (int i = 0; i < paintColors.length; i++) { map.put(progress_rate[i], paintColors[i]); } if (map.size() >0) { for (int i = 0; i < map.size(); i++) { if (progress == progress_rate[i]) { color = paintColors[i]; } } } if (!isEnabled){ color = "#00000000"; } return color; } public String getPaintColors2() { String color = "#000000"; HashMap<Integer, Object> map = new HashMap<>(); for (int i = 0; i < paintColors.length; i++) { map.put(progress_rate[i], paintColors[i]); } if (map.size() >0) { for (int i = 0; i < map.size(); i++) { if (progress2 == progress_rate[i]) { color = paintColors[i]; } } } if (getNumberOfPointers() == 1){ color = "#00000000"; } return color; } private boolean downOnArc = false; private int downOnPointNum = 0; public void setViewEnabled(boolean enabled) { isEnabled = enabled; if (isEnabled){ setAlpha(1f); }else { setAlpha(0.4f); } } @Override public boolean onTouchEvent(MotionEvent event) { if (!isEnabled){ return false; } int action = event.getAction(); int x = (int) event.getX(); int y = (int) event.getY(); switch (action) { case MotionEvent.ACTION_DOWN: if (isLightType()&&isTouchArc(x, y)) { downOnArc = true; if (isPointerOne(x,y) && downOnPointNum == 0){ updateArc(x, y,1); downOnPointNum = 1; } if (!isPointerOne(x,y) && downOnPointNum == 0){ updateArc(x, y,2); downOnPointNum = 2; } return true; } break; case MotionEvent.ACTION_MOVE: if (isLightType()&&downOnArc) { if (downOnPointNum == 1){ updateArc(x, y,1); }else { updateArc(x, y,2); } setUpVibration(); final ViewParent parent = getParent(); if (parent != null) { //通知父控件不要拦截事件 parent.requestDisallowInterceptTouchEvent(true); } return true; } break; case MotionEvent.ACTION_UP: downOnArc = false; downOnPointNum = 0; if (progress2 == progress){ if (progress2 == 24){ progress2 = progress - 1; }else { progress2 = progress + 1; } } invalidate(); if (isLightType()&&changeListener != null) { changeListener.onProgressChangeEnd(max, progress,progress2); if (!valueInTheDarkArea(progress)){ // 调用振动 LightEffectUtils.performKeyPressHapticFeedback(getContext(),this); } } break; } return super.onTouchEvent(event); } private void setUpVibration() { if (last_y != getProgress() && !valueInTheDarkArea(getProgress())){ for (int i = 0; i <progress_rate.length ; i++) { if (getProgress() == progress_rate[i]){ // 调用振动 LightEffectUtils.performKeyPressHapticFeedback(getContext(),this); last_y = getProgress(); } } } if (last_y2 != getProgress2() && !valueInTheDarkArea(getProgress2())){ for (int i = 0; i <progress_rate.length ; i++) { if (getProgress2() == progress_rate[i]){ // 调用振动 LightEffectUtils.performKeyPressHapticFeedback(getContext(),this); last_y2 = getProgress2(); } } } } private int centerX, centerY; private int radius; private int paddingOuterThumb; @Override protected void onSizeChanged(int width, int height, int oldw, int oldh) { centerX = width / 2; centerY = height / 2; int minCenter = Math.min(centerX, centerY); radius = (int) (minCenter - roundWidth / 2 - paddingOuterThumb); //圆环的半径 minValidateTouchArcRadius = (int) (radius - paddingOuterThumb * 1.5f); maxValidateTouchArcRadius = (int) (radius + paddingOuterThumb * 1.5f); super.onSizeChanged(width, height, oldw, oldh); } // 根据点的位置,更新进度 private void updateArc(int x, int y,int downOnPointNum) { // 当前移动或者点击位置 int cx = x - getWidth() / 2; int cy = y - getHeight() / 2; // 计算角度,得出(-1->1)之间的数据,等同于(-180°->180°) double angle = Math.atan2(cy, cx) / Math.PI; // 将角度转换成(0->2)之间的值,然后减去145°的偏移量 angle = ((2 + angle) % 2 - (145 / 180f)) % 2; // 用(0->2)之间的角度值乘以总进度,等于当前进度 // 当前变化进度 int i = (int) (angle * max / 2); int adjustProgress = progressFormatConversion(i); if (isLeftDarkArea(adjustProgress)){ adjustProgress = 0; }else if (isRightDarkArea(adjustProgress)){ adjustProgress = 24; } if (downOnPointNum == 1){ progress = adjustProgress; }else if(downOnPointNum == 2){ progress2 = adjustProgress; } if (changeListener != null) { changeListener.onProgressChange(max, progress,progress2); } invalidate(); } private int progressFormatConversion(int num){ switch (num){ case -14: num = 22; break; case -13: num = 23; break; case -12: num = 24; break; } return num; } // 判断是指针1 private boolean isPointerOne(int x, int y){ // 当前移动或者点击位置 int cx = x - getWidth() / 2; int cy = y - getHeight() / 2; // 计算角度,得出(-1->1)之间的数据,等同于(-180°->180°) double angle = Math.atan2(cy, cx) / Math.PI; // 将角度转换成(0->2)之间的值,然后减去145°的偏移量 angle = ((2 + angle) % 2 - (145 / 180f)) % 2; // 用(0->2)之间的角度值乘以总进度,等于当前进度 // 当前变化进度 int i = (int) (angle * max / 2); int adjustProgress = progressFormatConversion(i); if (isLeftDarkArea(adjustProgress)){ adjustProgress = 0; }else if (isRightDarkArea(adjustProgress)){ adjustProgress = 24; } if (getNumberOfPointers() != 1){ int abs1 = Math.abs(adjustProgress - progress); int abs2 = Math.abs(adjustProgress - progress2); if (abs1 > abs2){ return false; }else { return true; } }else { return true; } } private int minValidateTouchArcRadius; // 最小有效点击半径 private int maxValidateTouchArcRadius; // 最大有效点击半径 // 判断是否按在圆边上 private boolean isTouchArc(int x, int y) { double d = getTouchRadius(x, y); if (d >= minValidateTouchArcRadius && d <= maxValidateTouchArcRadius) { return true; } return false; } // 计算某点到圆点的距离 private double getTouchRadius(int x, int y) { int cx = x - getWidth() / 2; int cy = y - getHeight() / 2; return Math.hypot(cx, cy); } public synchronized int getMax() { return max; } /** * 设置进度的最大值 * * @param max */ public synchronized void setMax(int max) { if (max < 0) { throw new IllegalArgumentException("max not less than 0"); } this.max = max; } /** * 获取指针数量 * * @return */ public int getNumberOfPointers() { return numberOfPointers; } /** * 设置指针数量 * * @return */ public void setNumberOfPointers(int numberOfPointers) { this.numberOfPointers = numberOfPointers; } /** * 获取进度.需要同步 * * @return */ public synchronized int getProgress() { return progress; } /** * 获取进度.需要同步 * * @return */ public synchronized int getProgress2() { return progress2; } /** * 设置进度,此为线程安全控件,由于考虑多线的问题,需要同步 * 刷新界面调用postInvalidate()能在非UI线程刷新 * * @param mProgress */ public synchronized void setProgress(int mProgress) { if (mProgress < 0) { throw new IllegalArgumentException("progress not less than 0"); } if (mProgress > max) { progress = max; } if (mProgress <= max) { this.progress = mProgress; postInvalidate(); } } /** * 设置进度,此为线程安全控件,由于考虑多线的问题,需要同步 * 刷新界面调用postInvalidate()能在非UI线程刷新 * * @param mProgress2 */ public synchronized void setProgress2(int mProgress2) { if (mProgress2 < 0) { throw new IllegalArgumentException("progress2 not less than 0"); } if (mProgress2 > max) { progress2 = max; } if (mProgress2 <= max) { if (mProgress2 == progress){ if (progress2 == 24){ progress2 = progress - 1; }else { progress2 = progress + 1; } }else { this.progress2 = mProgress2; } postInvalidate(); } } public void setViewColorfulType(int type){ if (type == 2){ if (progress2 == progress){ if (progress2 == 24){ progress2 = progress - 1; }else { progress2 = progress + 1; } }else { progress2 = 0; } setNumberOfPointers(2); }else { progress2 = progress; setNumberOfPointers(1); } postInvalidate(); } /** * 根据手机的分辨率从 dp 的单位 转成为 px(像素) */ public static int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } /** * 根据手机的分辨率从 px(像素) 的单位 转成为 dp */ public static int px2dip(Context context, float pxValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); } /** * 是否是黑暗不可点击区域 * @param mProgress * @return */ public static boolean valueInTheDarkArea(int mProgress){ int[] progress = {-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1 }; for (int i = 0; i < progress.length; i++) { if (mProgress == progress[i]){ return true; } } return false; } /** * 是否是左区域 * @param mProgress * @return */ public static boolean isLeftDarkArea(int mProgress){ int [] progress = {-5,-4,-3,-2,-1}; for (int i = 0; i < progress.length; i++) { if (mProgress == progress[i]){ return true; } } return false; } /** * 是否是左区域 * @param mProgress * @return */ public static boolean isRightDarkArea(int mProgress){ int[] progress = {-11,-10,-9,-8,-7,-6}; for (int i = 0; i < progress.length; i++) { if (mProgress == progress[i]){ return true; } } return false; } /** * 依圆心坐标,半径,扇形角度,计算出扇形终射线与圆弧交叉点的xy坐标 * * @param cirX 圆centerX * @param cirY 圆centerY * @param radius 圆半径 * @param cirAngle 当前弧角度 * @param orginAngle 起点弧角度 * @return 扇形终射线与圆弧交叉点的xy坐标 */ public static PointF calcArcEndPointXY(float cirX, float cirY, float radius, float cirAngle, float orginAngle) { cirAngle = (orginAngle + cirAngle) % 360; return calcArcEndPointXYForDoom(cirX, cirY, radius, cirAngle); } /** * For Doom * 依圆心坐标,半径,扇形角度,计算出扇形终射线与圆弧交叉点的xy坐标 * * @param cirX 圆centerX * @param cirY 圆centerY * @param radius 圆半径 * @param cirAngle 当前弧角度 * @return 扇形终射线与圆弧交叉点的xy坐标 */ public static PointF calcArcEndPointXYForDoom(float cirX, float cirY, float radius, float cirAngle) { float posX = 0.0f; float posY = 0.0f; float arcAngle = 0.0f; //将角度转换为弧度 if (cirAngle<90&&cirAngle>28) { arcAngle = (float) (Math.PI * 28.0 / 180.0); }else { arcAngle = (float) (Math.PI * cirAngle / 180.0); } if (cirAngle < 90) { posX = cirX + (float) (Math.cos(arcAngle)) * radius; posY = cirY + (float) (Math.sin(arcAngle)) * radius; } else if (cirAngle == 90) { posX = cirX; posY = cirY + radius; } else if (cirAngle > 90 && cirAngle < 180) { if(cirAngle>90&&cirAngle<150.5){ arcAngle = (float) (Math.PI * (180 - 150.5) / 180.0); }else{ arcAngle = (float) (Math.PI * (180 - cirAngle) / 180.0); } posX = cirX - (float) (Math.cos(arcAngle)) * radius; posY = cirY + (float) (Math.sin(arcAngle)) * radius; } else if (cirAngle == 180) { posX = cirX - radius; posY = cirY; } else if (cirAngle > 180 && cirAngle < 270) { arcAngle = (float) (Math.PI * (cirAngle - 180) / 180.0); posX = cirX - (float) (Math.cos(arcAngle)) * radius; posY = cirY - (float) (Math.sin(arcAngle)) * radius; } else if (cirAngle == 270) { posX = cirX; posY = cirY - radius; } else { arcAngle = (float) (Math.PI * (360 - cirAngle) / 180.0); posX = cirX + (float) (Math.cos(arcAngle)) * radius; posY = cirY - (float) (Math.sin(arcAngle)) * radius; } return new PointF(posX, posY); } private OnProgressChangeListener changeListener; public void setChangeListener(OnProgressChangeListener changeListener) { this.changeListener = changeListener; } public interface OnProgressChangeListener { void onProgressChange(int duration, int progress ,int progress2); void onProgressChangeEnd(int duration, int progress ,int progress2); } public boolean isLightType() { return lightType; } public void setLightType(boolean lightType) { this.lightType = lightType; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。