缘起

最近在帮人做一个计步器,其中涉及到身高、体重等信息的采集;我参考了众多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实现不固定刻度的刻度尺
# 自定义
# 重写
# 过程中
# 都是
# 也有
# 有很多
# 它是
# 做一个
# 按下
# 涉及到
# 给个
# 帮人
# 回调
# 书上
# 太不
# 内嵌
# 新建一个
# 类中
# 觉得该
# 最小值
相关文章:
建站ABC备案流程中有哪些关键注意事项?
音响网站制作视频教程,隆霸音响官方网站?
义乌企业网站制作公司,请问义乌比较好的批发小商品的网站是什么?
韩国服务器如何优化跨境访问实现高效连接?
网站制作新手教程,新手建设一个网站需要注意些什么?
建站之星安装提示数据库无法连接如何解决?
如何在Golang中实现微服务服务拆分_Golang微服务拆分与接口管理方法
微网站制作教程,我微信里的网站怎么才能复制到浏览器里?
,想在网上投简历,哪几个网站比较好?
Python文件管理规范_工程实践说明【指导】
如何在服务器上配置二级域名建站?
如何在宝塔面板中修改默认建站目录?
常州企业网站制作公司,全国继续教育网怎么登录?
如何选择PHP开源工具快速搭建网站?
制作营销网站公司,淘特是干什么用的?
图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?
详解免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)
,制作一个手机app网站要多少钱?
如何在阿里云域名上完成建站全流程?
,在苏州找工作,上哪个网站比较好?
建站168自助建站系统:快速模板定制与SEO优化指南
网站制作的软件有哪些,制作微信公众号除了秀米还有哪些比较好用的平台?
如何实现建站之星域名转发设置?
长沙企业网站制作哪家好,长沙水业集团官方网站?
网站制作难吗安全吗,做一个网站需要多久时间?
高性能网站服务器配置指南:安全稳定与高效建站核心方案
网站网页制作专业公司,怎样制作自己的网页?
大同网页,大同瑞慈医院官网?
如何通过FTP服务器快速搭建网站?
黑客入侵网站服务器的常见手法有哪些?
如何快速生成橙子建站落地页链接?
如何在宝塔面板创建新站点?
如何通过IIS搭建网站并配置访问权限?
在线教育网站制作平台,山西立德教育官网?
建站之星安装步骤有哪些常见问题?
简历在线制作网站免费,免费下载个人简历的网站是哪些?
焦点电影公司作品,电影焦点结局是什么?
小自动建站系统:AI智能生成+拖拽模板,多端适配一键搭建
制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?
如何在Golang中使用replace替换模块_指定本地或远程路径
制作假网页,招聘网的薪资待遇,会有靠谱的吗?一面试又各种折扣?
名字制作网站免费,所有小说网站的名字?
网站制作和推广的区别,想自己建立一个网站做推广,有什么快捷方法马上做好一个网站?
建站之星云端配置指南:模板选择与SEO优化一键生成
湖州网站制作公司有哪些,浙江中蓝新能源公司官网?
定制建站是什么?如何实现个性化需求?
C++如何编写函数模板?(泛型编程入门)
C++如何将C风格字符串(char*)转换为std::string?(代码示例)
建站之星收费标准详解:套餐费用及年费价格表一览
武清网站制作公司,天津武清个人营业执照注销查询系统网站?
*请认真填写需求信息,我们会在24小时内与您取得联系。