缘起

最近在帮人做一个计步器,其中涉及到身高、体重等信息的采集;我参考了众多app的实现,觉得"乐动力"中滑动刻度的方式比较优雅。于是乎,反编译了该app,结果发现它是采用图片的方式实现的,即ScrollView内嵌了一张带刻度的图片。
个人觉得该方式太不灵活,且对美工的依赖较大,于是便想自定义一个刻度尺控件。
需求分析
涉及的知识点
最终效果
由于简书上无法嵌入gif,为不影响效果,请移步github查看,如果觉得不错,帮忙给个star ^_^https://github.com/LichFaker/ScaleView
实现过程
1、新建一个class:HorizontalScaleScrollView, 继承自View
2、在构造方法中获取自定义属性:
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());
}
3、重写onMeasure,计算中间刻度
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height=MeasureSpec.makeMeasureSpec(mRectHeight, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, height);
mScaleScrollViewRange = getMeasuredWidth();
mTempScale = mScaleScrollViewRange / mScaleMargin / 2 + mMin;
mMidCountScale = mScaleScrollViewRange / mScaleMargin / 2 + mMin;
}
4、重写onDraw,绘制刻度和指针
protected void onDrawScale(Canvas canvas, Paint paint) {
paint.setTextSize(mRectHeight / 4);
for (int i = 0, k = mMin; i <= mMax - mMin; i++) {
if (i % 10 == 0) {
//整值
canvas.drawLine(i * mScaleMargin, mRectHeight, i * mScaleMargin, mRectHeight - mScaleMaxHeight, paint);
//整值文字
canvas.drawText(String.valueOf(k), i * mScaleMargin, mRectHeight - mScaleMaxHeight - 20, paint);
k += 10;
} else {
canvas.drawLine(i * mScaleMargin, mRectHeight, i * mScaleMargin, mRectHeight - mScaleHeight, paint);
}
}
}
protected void onDrawPointer(Canvas canvas, Paint paint) {
paint.setColor(Color.RED);
//每一屏幕刻度的个数/2
int countScale = mScaleScrollViewRange / mScaleMargin / 2;
//根据滑动的距离,计算指针的位置【指针始终位于屏幕中间】
int finalX = mScroller.getFinalX();
//滑动的刻度
int tmpCountScale = (int) Math.rint((double) finalX / (double) mScaleMargin);//四舍五入取整
//总刻度
mCountScale = tmpCountScale + countScale + mMin;
if (mScrollListener != null) { //回调方法
mScrollListener.onScaleScroll(mCountScale);
}
canvas.drawLine(countScale * mScaleMargin + finalX, mRectHeight,
countScale * mScaleMargin + finalX, mRectHeight - mScaleMaxHeight - mScaleHeight, paint);
}
处理滑动事件
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (mScroller != null && !mScroller.isFinished()) {
mScroller.abortAnimation();
}
mScrollLastX = x;
return true;
case MotionEvent.ACTION_MOVE:
int dataX = mScrollLastX - x;
if (mCountScale - mTempScale < 0) { //向右边滑动
if (mCountScale <= mMin && dataX <= 0) //禁止继续向右滑动
return super.onTouchEvent(event);
} else if (mCountScale - mTempScale > 0) { //向左边滑动
if (mCountScale >= mMax && dataX >= 0) //禁止继续向左滑动
return super.onTouchEvent(event);
}
smoothScrollBy(dataX, 0);
mScrollLastX = x;
postInvalidate();
mTempScale = mCountScale;
return true;
case MotionEvent.ACTION_UP:
if (mCountScale < mMin) mCountScale = mMin;
if (mCountScale > mMax) mCountScale = mMax;
int finalX = (mCountScale - mMidCountScale) * mScaleMargin;
mScroller.setFinalX(finalX); //纠正指针位置
postInvalidate();
return true;
}
return super.onTouchEvent(event);
}
最后的说明
以上只是针对水平滑动刻度的实现,垂直滑动原理一致,在源码中已经实现,其中也有许多不够完善的地方,如:
# Android滚动刻度尺
# Android实现刻度尺
# Android
# 刻度尺
# Android自定义控件之刻度尺控件
# Android实现滑动刻度尺效果
# Android实现自定义滑动刻度尺方法示例
# Android自定义RecyclerView实现不固定刻度的刻度尺
# 自定义
# 重写
# 过程中
# 都是
# 也有
# 有很多
# 它是
# 做一个
# 按下
# 涉及到
# 给个
# 帮人
# 回调
# 书上
# 太不
# 内嵌
# 新建一个
# 类中
# 觉得该
# 最小值
相关文章:
如何在橙子建站中快速调整背景颜色?
C#如何在一个XML文件中查找并替换文本内容
微信小程序制作网站有哪些,微信小程序需要做网站吗?
网站制作价目表怎么做,珍爱网婚介费用多少?
建站之家VIP精选网站模板与SEO优化教程整合指南
如何在IIS管理器中快速创建并配置网站?
中山网站推广排名,中山信息港登录入口?
在线教育网站制作平台,山西立德教育官网?
行程制作网站有哪些,第三方机票电子行程单怎么开?
c# 在ASP.NET Core中管理和取消后台任务
建站主机与服务器功能差异如何区分?
详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)
网站按钮制作软件,如何实现网页中按钮的自动点击?
韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南
建站之星如何实现网站加密操作?
零基础网站服务器架设实战:轻量应用与域名解析配置指南
实现点击下箭头变上箭头来回切换的两种方法【推荐】
官网自助建站系统:SEO优化+多语言支持,快速搭建专业网站
建站之星五站合一营销型网站搭建攻略,流量入口全覆盖优化指南
宁波免费建站如何选择可靠模板与平台?
如何快速打造个性化非模板自助建站?
建站之星如何开启自定义404页面避免用户流失?
为什么Go需要go mod文件_Go go mod文件作用说明
建站之星导航配置指南:自助建站与SEO优化全解析
如何快速生成高效建站系统源代码?
h5网站制作工具有哪些,h5页面制作工具有哪些?
小程序网站制作需要准备什么资料,如何制作小程序?
如何通过西部数码建站助手快速创建专业网站?
制作销售网站教学视频,销售网站有哪些?
韩国服务器如何优化跨境访问实现高效连接?
h5在线制作网站电脑版下载,h5网页制作软件?
建站之星24小时客服电话如何获取?
商务网站制作工程师,从哪几个方面把握电子商务网站主页和页面的特色设计?
如何快速搭建安全的FTP站点?
如何在景安云服务器上绑定域名并配置虚拟主机?
临沂网站制作企业,临沂第三中学官方网站?
如何生成腾讯云建站专用兑换码?
Bpmn 2.0的XML文件怎么画流程图
贸易公司网站制作流程,出口贸易网站设计怎么做?
无锡营销型网站制作公司,无锡网选车牌流程?
如何在VPS电脑上快速搭建网站?
个人网站制作流程图片大全,个人网站如何注销?
如何在沈阳梯子盘古建站优化SEO排名与功能模块?
智能起名网站制作软件有哪些,制作logo的软件?
兔展官网 在线制作,怎样制作微信请帖?
巅云智能建站系统:可视化拖拽+多端适配+免费模板一键生成
广平建站公司哪家专业可靠?如何选择?
公众号网站制作网页,微信公众号怎么制作?
宝塔面板创建网站无法访问?如何快速排查修复?
javascript中的try catch异常捕获机制用法分析
*请认真填写需求信息,我们会在24小时内与您取得联系。