做过的自定义 View
2024-10-21 09:10:57
做过的自定义 View
android
view
custom
音频条状图
需求
音频图
最终效果类似于音频图中的条状图
只是效果模拟,并不监听真实的音频
条的宽度相同,高度随机;条的颜色是红到黄的线性渐变
随着时间的变化,条的高度发生变化
详细设计
自定义属性
条的宽度(默认 3dp)
条的颜色变化范围(两个颜色——默认红色、橙色)
条之间的间距
整个 View 的背景颜色
变化的频率,单位是毫秒
处理起始绘制的坐标,并结合条间距计算 View 能显示多少个条。计算方法:条的总数 = (View 的宽度 - 条间距 * 2) / (条的宽度 + 条间距)
随机生成条的高度,高度的范围:[1, 控件的高度]
条的颜色在两个颜色之间,随时间呈线性梯度变化
具体实现
定义自定义属性(res/values/attrs.xml):
<declare-styleable name="AudioBarChart">
<attr name="barWidth" format="reference|dimension" /><!-- 条的宽度,默认 3dp -->
<attr name="barStartColor" format="reference|color" /><!-- 条颜色的起始值,默认红色 -->
<attr name="barEndColor" format="reference|color" /><!-- 条颜色的结束值,默认橙色 -->
<attr name="barSpace" format="reference|dimension" /><!-- 条间距,默认 1dp -->
<attr name="wholeBgColor" format="reference|color" /><!-- 整个的背影颜色,默认白色 -->
<attr name="changeFrenquency" format="integer" /><!-- 条变化的频率,单位毫秒,默认 300 -->
</declare-styleable>
获取自定义属性并指定默认值:
public AudioBarChart(Context context, AttributeSet attrs) {
super(context, attrs); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.AudioBarChart); mBarWidth = (int) typedArray.getDimension(R.styleable.AudioBarChart_barWidth, 20);
mBarStartColor = typedArray.getColor(R.styleable.AudioBarChart_barStartColor, getResources().getColor(R.color.audio_bar_chart_red));
mBarEndColor = typedArray.getColor(R.styleable.AudioBarChart_barEndColor, getResources().getColor(R.color.audio_bar_chart_orange));
mBarSpace = (int) typedArray.getDimension(R.styleable.AudioBarChart_barSpace, 5);
mWholeBgColor = typedArray.getColor(R.styleable.AudioBarChart_wholeBgColor, getResources().getColor(android.R.color.white));
mChangeFrequency = typedArray.getInt(R.styleable.AudioBarChart_changeFrenquency, 300); typedArray.recycle();
}
测量并初始化变量值:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec); mWidth = MeasureSpec.getSize(widthMeasureSpec);
mHeight = MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension(mWidth, mHeight); mBarPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBarPaint.setStyle(Paint.Style.FILL); mBarCount = (mWidth - mBarSpace * 2) / (mBarWidth + mBarSpace);
}
绘制:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas); setBackgroundColor(mWholeBgColor);
for (int i = 0; i < mBarCount; i++) {
int height = mHeight - new Random().nextInt(mHeight * 3 / 4);
int x = (i + 1) * mBarSpace + i * mBarWidth;
Rect rect = new Rect(x, height, x + mBarWidth, mHeight);
mLinearGradient = new LinearGradient(x, mHeight, x + mBarWidth, height, mBarStartColor, mBarEndColor, Shader.TileMode.CLAMP);
mBarPaint.setShader(mLinearGradient);
canvas.drawRect(rect, mBarPaint);
}
postInvalidateDelayed(mChangeFrequency);
}
最终效果:
最终效果
最新文章
- ASP.NET MVC之文件上传【二】(九)
- 个人psp
- java Http原生 Get 和Post 支持代理认证
- 查看Oracle SQL执行计划的常用方式
- 字符串相似度算法(编辑距离算法 Levenshtein Distance)
- YII缓存Cache
- Windows XP CD 函数不正确
- 12个高矮不同的人,排成两排(catalan数)
- hdu3496(二维背包)
- cuda学习2-block与thread数量的选取
- 【python】字符串格式化
- OpenCV 金字塔图像缩放
- Java NIO系列1-概观
- 持续集成(Continuous Integration)基本概念与实践
- BZOJ 1934 Vote 善意的投票(最小割+二分图)
- 在 C# 中,如何发现死锁并防止死锁
- mvn deploy命令上传包
- VC++实现获取文件占用空间大小的两种方法(非文件大小)
- ballerina 学习 三十二 编写安全的程序
- 转载 spring事务增强
热门文章
- MongoDB分片集群节点状态stateStr:RECOVERING解决
- 在centos中安装mysql详细步骤说明
- 怎样推断多个字段组成的keyword在另外一张表中是否存在
- async -- await 解决数据异步获取
- 读-《c++设计新思维-泛型编程与设计模式之应用》经典记录(英文书名:《modern c++ design》)
- 创建了几个String对象?
- 采用QHD分辨率使用kinect2_calibration,完成QHD图像校正
- angular过滤器使用 自定义过滤器
- javascript解析器(引擎)
- 百度地图和高德地图坐标系的互相转换 四种Sandcastle方法生成c#.net帮助类帮助文档 文档API生成神器SandCastle使用心得 ASP.NET Core