新浦京81707con > 软件下载 > 葡京线上开户的卷尺效果,Android滚动刻度尺实现

原标题:葡京线上开户的卷尺效果,Android滚动刻度尺实现

浏览次数:61 时间:2020-03-01

纵向滑动刻度尺

本篇作品同不经常候收音和录音在本身的私人民居房博客:自定义 view 之银丹草 app 的卷尺效果

最近在帮人做三个计程表,在这之中提到到身高、体重等讯息的采撷;小编参谋了非常多app的完结,感觉"乐引力"中滑动刻度的方法相比较崇高。于是乎,反编写翻译了该app,结果开掘它是应用图片的办法贯彻的,即ScrollView内嵌了一张带刻度的图形。个人感到该办法太不灵便,且对美术的注重极大,于是便想自定义三个刻度尺控件。

葡京线上开户 1VerticalScaleView.png

前些天见到 HenCoder「仿写酷分界面」活动——征稿 ,扔物线大大找了多少个超级帅炫的成效让读者们仿写,最终选出的著作效果也很好,可是并未有批注实现思路,比相当多少人依然不知道怎么办,所以小编主宰本人入手撸一篇文章记录下学习进度,光看外人写的,本人不动手长久也学不会啊是啊。

  1. 制图刻度,区分整值刻度和平日刻度

横向滑动刻度尺

本身看了多少个野薄荷卷尺的源码,这里记录下一种完毕思路,不必然是最优的主意,仅供就学参照他事他说加以考察。

  • 庚申革命指针始终在刻度尺的高级中学级,表示方今的刻度
  • 刻度的最大值和渺小值可动态设置
  • 刻度尺的中度或宽度可安装,设置后中间刻度不改变
  • 可滑动,滑动后当前刻度随之转移

葡京线上开户 2HorizontalScaleView.png

先看成效呢,

  1. View的机制

贯彻思路:onDraw方法中画出全体刻度尺和指针。重写onTouchEvent,依照手指的滑行不断更改坐标,并再一次总括出刻度对应的坐标甚至指针所指向坐标对应的刻度,然后重绘。具体的绘图方法参谋源码,大概正是找到每种点的坐标然后用canvas的呼应措施绘制,总括比超级多但不复杂~

葡京线上开户 3

  • canvas绘图
  • Scroller工具类的行使
  • 自定义View的属性
  • 点击、滑动事件的拍卖

那边未有用Scroller达成滑动,因为Scroller滑动时整个View都会滑动,而笔者期望的功力是刻度滑动,中间的指针不动,尝试了三种滑动方法后意识依然重绘的效果最佳。即透过手指滑动的偏移量总结新的坐标,然后依据新坐标重绘视图。

先看张我画的张图,

出于简书上不能够松开gif,为不影响意义,请移步github查看,如若认为不错,协助给个star _

除此以外,使用VelocityTracker记录手指抬起的速度,达成惯性滑动的功用。源码如下:

葡京线上开户 4

  1. 新建三个class:HorizontalScaleScrollView, 世襲自View
public class VerticalScaleView extends View { private final int SCALE_WIDTH_BIG = 4;//大刻度线宽度 private final int SCALE_WIDTH_SMALL = 2;//小刻度线宽度 private final int LINE_WIDTH = 6;//指针线宽度 private int rectPadding = 20;//圆角矩形间距 private int rectHeight;//圆角矩形高 private int maxScaleLength;//大刻度长度 private int midScaleLength;//中刻度长度 private int minScaleLength;//小刻度长度 private int scaleSpace;//刻度间距 private int scaleSpaceUnit;//每大格刻度间距 private int height, width;//view高宽 private int ruleWidth;//刻度尺宽 private int max;//最大刻度 private int min;//最小刻度 private int borderUp, borderDown;//上下边界值坐标 private float midY;//当前中心刻度y坐标 private float originMidY;//初始中心刻度y坐标 private float minY;//最小刻度y坐标,从最小刻度开始画刻度 private float lastY; private float originValue;//初始刻度对应的值 private float currentValue;//当前刻度对应的值 private Paint paint;//画笔 private Context context; private String descri = "身高";//描述 private String unit = "cm";//刻度单位 private VelocityTracker velocityTracker;//速度监测 private float velocity;//当前滑动速度 private float a = 1000000;//加速度 private boolean continueScroll;//是否继续滑动 private boolean isMeasured; private OnValueChangeListener onValueChangeListener; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { if (null != onValueChangeListener) { float v =  (Math.round(currentValue * 10)) / 10;//保留一位小数 onValueChangeListener.onValueChanged; } } }; public VerticalScaleView(Context context) { super; this.context = context; init(); } public VerticalScaleView(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; init(); } public VerticalScaleView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.context = context; init(); } private void init() { //初始化画笔 paint = new Paint(); paint.setAntiAlias; paint.setDither; } //设置刻度范围 public void setRange(int min, int max) { this.min = min; this.max = max; originValue = (max   min) / 2; currentValue = originValue; } //设置刻度单位 public void setUnit(String unit) { this.unit = unit; } //设置刻度描述 public void setDescri(String descri) { this.descri = descri; } //设置value变化监听 public void setOnValueChangeListener(OnValueChangeListener onValueChangeListener) { this.onValueChangeListener = onValueChangeListener; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (!isMeasured) { width = getMeasuredWidth(); height = getMeasuredHeight(); ruleWidth = width * 2 / 3; maxScaleLength = width / 5; midScaleLength = width / 6; minScaleLength = maxScaleLength / 2; scaleSpace = height / 80 > 8 ? height / 80 : 8; scaleSpaceUnit = scaleSpace * 10   SCALE_WIDTH_BIG   SCALE_WIDTH_SMALL * 9; rectHeight = scaleSpaceUnit / 2; borderUp = height / 2 - ((min   max) / 2 - min) * scaleSpaceUnit; borderDown = height / 2   ((min   max) / 2 - min) * scaleSpaceUnit; midY = (borderUp   borderDown) / 2; originMidY = midY; minY = borderDown; isMeasured = true; } } @Override protected void onDraw(Canvas canvas) { super.onDraw; //画刻度线 for (int i = min; i <= max; i  ) { //画刻度数字 canvas.rotate; Rect rect = new Rect(); String str = String.valueOf; paint.setColor(getResources().getColor(R.color.black)); paint.setTextSize; paint.getTextBounds(str, 0, str.length; int w = rect.width(); int h = rect.height(); canvas.drawText(str, minY -  * scaleSpaceUnit - w / 2 - SCALE_WIDTH_BIG / 2, -(ruleWidth - maxScaleLength - h - minScaleLength / 2), paint); canvas.rotate; //画大刻度线 paint.setStrokeWidth(SCALE_WIDTH_BIG); canvas.drawLine(ruleWidth, minY -  * scaleSpaceUnit, ruleWidth - maxScaleLength, minY -  * scaleSpaceUnit, paint); if  { continue;//最后一条不画中小刻度线 } //画中刻度线 paint.setStrokeWidth(SCALE_WIDTH_SMALL); canvas.drawLine(ruleWidth, minY -  * scaleSpaceUnit   scaleSpaceUnit / 2, ruleWidth - midScaleLength, minY -  * scaleSpaceUnit   scaleSpaceUnit / 2, paint); //画小刻度线 for (int j = 1; j < 10; j  ) { if  { continue; } canvas.drawLine(ruleWidth, minY -  * scaleSpaceUnit   (SCALE_WIDTH_SMALL   scaleSpace) * j, ruleWidth - minScaleLength, minY -  * scaleSpaceUnit   (SCALE_WIDTH_SMALL   scaleSpace) * j, paint); } } //画竖线 paint.setStrokeWidth(LINE_WIDTH); paint.setColor(getResources().getColor(R.color.gray)); canvas.drawLine(ruleWidth   LINE_WIDTH / 2, minY   SCALE_WIDTH_BIG / 2, ruleWidth   LINE_WIDTH / 2, minY - (max - min) * scaleSpaceUnit - SCALE_WIDTH_BIG / 2, paint); //画指针线 paint.setColor(getResources().getColor(R.color.colorPrimaryDark)); canvas.drawLine(0, height / 2, ruleWidth, height / 2, paint); //画圆角矩形 paint.setStyle(Paint.Style.FILL); RectF r = new RectF(); r.left = ruleWidth   rectPadding; r.top = height / 2 - rectHeight / 2; r.right = width; r.bottom = height / 2   rectHeight / 2; canvas.drawRoundRect(r, 10, 10, paint); //画小三角形指针 Path path = new Path(); path.moveTo(ruleWidth   rectPadding, height / 2 - scaleSpace); path.lineTo(ruleWidth   rectPadding - 8, height / 2); path.lineTo(ruleWidth   rectPadding, height / 2   scaleSpace); path.close(); canvas.drawPath(path, paint); //绘制文字 paint.setColor(getResources().getColor(R.color.black)); Rect rect1 = new Rect(); paint.getTextBounds(descri, 0, descri.length; int w1 = rect1.width(); canvas.drawText(descri, width - (width - ruleWidth - 20) / 2 - w1 / 2, height / 2 - rectHeight / 2 - 10, paint); //绘制当前刻度值数字 paint.setColor(getResources().getColor(R.color.white)); float v =  (Math.round(currentValue * 10)) / 10;//保留一位小数 String value = String.valueOf   unit; Rect rect2 = new Rect(); paint.getTextBounds(value, 0, value.length; int w2 = rect2.width(); int h2 = rect2.height(); canvas.drawText(value, width - (width - ruleWidth - 20) / 2 - w2 / 2, height / 2   h2 / 2, paint); } @Override public boolean onTouchEvent(MotionEvent event) { float y = event.getY(); switch (event.getAction { case MotionEvent.ACTION_DOWN: lastY = y; continueScroll = false; //初始化速度追踪 if (velocityTracker == null) { velocityTracker = VelocityTracker.obtain(); } else { velocityTracker.clear(); } break; case MotionEvent.ACTION_MOVE: velocityTracker.addMovement; int offsetY =  (lastY - y); minY -= offsetY; midY -= offsetY; calculateCurrentScale(); invalidate(); lastY = y; break; case MotionEvent.ACTION_UP: confirmBorder(); //当前滑动速度 velocityTracker.computeCurrentVelocity; velocity = velocityTracker.getYVelocity(); float minVelocity = ViewConfiguration.get.getScaledMinimumFlingVelocity(); if (Math.abs > minVelocity) { continueScroll = true; continueScroll(); } else { velocityTracker.recycle(); velocityTracker = null; } break; case MotionEvent.ACTION_CANCEL: velocityTracker.recycle(); velocityTracker = null; break; } return true; } //计算当前刻度 private void calculateCurrentScale() { float offsetTotal = originMidY - midY; int offsetBig =  (offsetTotal / scaleSpaceUnit);//移动的大刻度数 float offsetS = offsetTotal % scaleSpaceUnit; int offsetSmall = (new BigDecimal(offsetS / (scaleSpace   SCALE_WIDTH_SMALL)).setScale(0, BigDecimal.ROUND_HALF_UP)).intValue();//移动的小刻度数 四舍五入取整 float offset = offsetBig   offsetSmall * 0.1f; if (originValue - offset > max) { currentValue = max; } else if (originValue - offset < min) { currentValue = min; } else { currentValue = originValue - offset; } mHandler.sendEmptyMessage; } //指针线超出范围时 重置回边界处 private void confirmBorder() { if (midY < borderUp) { midY = borderUp; minY = borderDown   (borderUp - borderDown) / 2; postInvalidate(); } else if (midY > borderDown) { midY = borderDown; minY = borderDown - (borderUp - borderDown) / 2; postInvalidate(); } } //手指抬起后继续惯性滑动 private void continueScroll() { new Thread(new Runnable() { @Override public void run() { float velocityAbs = 0;//速度绝对值 if (velocity > 0 && continueScroll) { velocity -= 50; minY  = velocity * velocity / a; midY  = velocity * velocity / a; velocityAbs = velocity; } else if (velocity < 0 && continueScroll) { velocity  = 50; minY -= velocity * velocity / a; midY -= velocity * velocity / a; velocityAbs = -velocity; } calculateCurrentScale(); confirmBorder(); postInvalidate(); if (continueScroll && velocityAbs > 0) { post; } else { continueScroll = false; } } }).start(); }}

能够动脑筋成有一把尺子在荧屏方面左右滑动,需求绘制的局地正是尺子和显示屏重合的片段,那么绘制的关键点正是找到第八个刻度线之处。

  • 在布局方法中得到自定义属性:

源码下载

葡京线上开户 5

那正是说这里便是计量线段 E 的长度了,思路如下:

protected void init(AttributeSet attrs) { // 获取自定义属性 TypedArray ta = getContext().obtainStyledAttributes(attrs, ATTR); mMin = ta.getInteger(LF_SCALE_MIN, 0); mMax = ta.getInteger(LF_SCALE_MAX, 200); mScaleMargin = ta.getDimensionPixelOffset(LF_SCALE_MARGIN, 15); mScaleHeight = ta.getDimensionPixelOffset(LF_SCALE_HEIGHT, 20); ta.recycle(); mScroller = new Scroller(getContext; }

E=F-DD=C

本文由新浦京81707con发布于软件下载,转载请注明出处:葡京线上开户的卷尺效果,Android滚动刻度尺实现

关键词: 新浦京81707con Android 自定义 刻度尺 卷尺

上一篇:RecycleView实现混合Item布局

下一篇:没有了