Android自定义View实现仿QQ实现运动步数效果
效果图:

1、attrs.xml中
<declare-styleable name="QQStepView">
<attr name="outerColor" format="color"/>
<attr name="innerColor" format="color"/>
<attr name="borderWidth" format="dimension"/>
<attr name="stepViewTextSize" format="dimension"/>
<attr name="stepViewTextColor" format="color"/>
</declare-styleable>
2、QQStepView
public class QQStepView extends View {
private int mOuterColor = Color.GRAY;
private int mInnerColor = Color.RED;
private float mBorderWidth = 20.0f;//20代表的20px
private float mStepViewTextSize = 12.0f;
private int mStepViewTextColor = Color.BLACK;
private Paint mOutPaint;
private int mStepMax;//最大的数值
private int mCurrentStep;//当前的数值
private Paint mInnerPaint;
private Paint mTextPaint;
public QQStepView(Context context) {
this(context, null);
}
public QQStepView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public QQStepView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//1分析效果
//2确定自定义属性,编写attr.xml
//3在布局中使用
//4在自定义View中获取自定义属性
//5onMeasure
//6onDraw
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.QQStepView);
mOuterColor = array.getColor(R.styleable.QQStepView_outerColor, mOuterColor);
mInnerColor = array.getColor(R.styleable.QQStepView_innerColor, mInnerColor);
mBorderWidth = array.getDimension(R.styleable.QQStepView_borderWidth, mBorderWidth);
mStepViewTextColor = array.getColor(R.styleable.QQStepView_stepViewTextColor, mStepViewTextColor);
mStepViewTextSize = array.getDimension(R.styleable.QQStepView_stepViewTextSize, mStepViewTextSize);
array.recycle();
//外层圆弧画笔
mOutPaint = new Paint();
mOutPaint.setAntiAlias(true);
mOutPaint.setStrokeWidth(mBorderWidth);
mOutPaint.setColor(mOuterColor);
mOutPaint.setStrokeCap(Paint.Cap.ROUND);//两端变圆弧
// mOutPaint.setStyle(Paint.Style.FILL);
mOutPaint.setStyle(Paint.Style.STROKE);
//内层圆弧画笔
mInnerPaint = new Paint();
mInnerPaint.setAntiAlias(true);
mInnerPaint.setStrokeWidth(mBorderWidth);
mInnerPaint.setColor(mInnerColor);
mInnerPaint.setStrokeCap(Paint.Cap.ROUND);//两端变圆弧
// mOutPaint.setStyle(Paint.Style.FILL);
mInnerPaint.setStyle(Paint.Style.STROKE);
//文字画笔
mTextPaint = new Paint();
mInnerPaint.setAntiAlias(true);
mInnerPaint.setColor(mStepViewTextColor);
mTextPaint.setTextSize(mStepViewTextSize);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//在布局文件中,可能wrap_content,可能高宽不一致
//获取模式 AT_MOST
//宽度高度不一致时取最小值,保持是个正方形
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width > height ? height : width, width > height ? height : width);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画外圆弧:
// int center = getWidth() / 2;
// int radius= (int) (getWidth()/2-mBorderWidth/2);
// RectF rectF = new RectF(center-radius, center-radius, center+radius, center+radius);
// int radius = (int) (getWidth() / 2 - mBorderWidth / 2);
RectF rectF = new RectF(mBorderWidth / 2, mBorderWidth / 2, getWidth() - mBorderWidth / 2,
getWidth() - mBorderWidth / 2);
canvas.drawArc(rectF, 135, 270, false, mOutPaint);
//画内圆弧:百分比,由用户设置的
if (mStepMax == 0) {
return;//防止第一次进入时为0,引起错误
}
float sweepAngle = (float) mCurrentStep / mStepMax;
canvas.drawArc(rectF, 135, sweepAngle * 270, false, mInnerPaint);
//画文字
String stepText = mCurrentStep + "";
Rect textBounds = new Rect();
mTextPaint.getTextBounds(stepText, 0, stepText.length(), textBounds);
int dx = getWidth() / 2 - textBounds.width() / 2;//文字的起始位置
//基线
Paint.FontMetricsInt fontMetricsInt = mTextPaint.getFontMetricsInt();
int dy = (fontMetricsInt.bottom = fontMetricsInt.top) - fontMetricsInt.bottom;
int baseLine = getHeight() / 2 + dy;
canvas.drawText(stepText, dx, baseLine, mTextPaint);
}
//其他,动画效果等
public synchronized void setStepMax(int stepMax) {
this.mStepMax = stepMax;
}
// synchronized,防止多线程操作出错
public synchronized void setCurrentStep(int currentStep) {
this.mCurrentStep = currentStep;
//不断绘制
invalidate();
}
}
3、在Activity布局中
<com.siberiadante.view.QQStepView
android:id="@+id/step_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
app:borderWidth="10dp"
app:innerColor="@color/blue"
app:outerColor="@color/colorAccent"
app:stepViewTextColor="@color/blue"
app:stepViewTextSize="28sp" />
4、在Activity中
mTvStart = (TextView) findViewById(R.id.tv_start);
stepView = (QQStepView) findViewById(R.id.step_view);
stepView.setStepMax(10000);
// stepView.setCurrentStep(5000);
//属性动画
final ValueAnimator valueAnimator = ObjectAnimator.ofFloat(0, 9000);
valueAnimator.setDuration(3000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
float value = (float) valueAnimator.getAnimatedValue();
stepView.setCurrentStep((int)value);
}
});
mTvStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
valueAnimator.start(); }
});
}
我的微信公众号:tstongxiao

参考文章:http://www.jianshu.com/p/4e0eb9bb09ab
Android自定义View实现仿QQ实现运动步数效果的更多相关文章
- Android自定义View 画弧形,文字,并增加动画效果
一个简单的Android自定义View的demo,画弧形,文字,开启一个多线程更新ui界面,在子线程更新ui是不允许的,但是View提供了方法,让我们来了解下吧. 1.封装一个抽象的View类 B ...
- android自定义View之仿通讯录侧边栏滑动,实现A-Z字母检索
我们的手机通讯录一般都有这样的效果,如下图: OK,这种效果大家都见得多了,基本上所有的android手机通讯录都有这样的效果.那我们今天就来看看这个效果该怎么实现. 一.概述 1.页面功能分析 整体 ...
- Android 自定义View,仿微信视频播放按钮
闲着,尝试实现了新版微信视频播放按钮,使用的是自定义View,先来个简单的效果图...真的很简单哈. 由于暂时用不到,加上时间原因,加上实在是没意思,加上……,本控件就没有实现自定义属性,有兴趣的朋友 ...
- Android 自定义View修炼-仿QQ5.0 的侧滑菜单效果的实现
有一段时间没有写博客了,最近比较忙,没什么时间写,刚好今天有点时间, 我就分享下,侧滑菜单的实现原理,一般android侧滑的实现原理和步骤如下:(源码下载在下面最后给出哈) 1.使用ViewGrou ...
- Android自定义view之仿微信录制视频按钮
本文章只写了个类似微信的录制视频的按钮,效果图如下: 一.主要的功能: 1.长按显示进度条,单击事件,录制完成回调 2.最大时间和最小时间控制 3.进度条宽度,颜色设置 二.实 ...
- Android 自定义View修炼-仿360手机卫士波浪球进度的实现
像360卫士的波浪球进度的效果,一般最常用的方法就是 画线的方式,先绘sin线或贝塞尔曲线,然后从左到右绘制竖线,然后再裁剪圆区域. 今天我这用图片bitmap的方式,大概的方法原理是: (1)首先用 ...
- android桌面悬浮窗仿QQ手机管家加速效果
主要还是用到了WindowManager对桌面悬浮进行管理. 需要一个火箭的悬浮窗 一个发射台悬浮窗 ,判断火箭是否放到了发射台,如果放上了,则使用AsyTask 慢慢将火箭的图片往上移.结束后., ...
- Android自定义View之ProgressBar出场记
关于自定义View,我们前面已经有三篇文章在介绍了,如果筒子们还没阅读,建议先看一下,分别是android自定义View之钟表诞生记.android自定义View之仿通讯录侧边栏滑动,实现A-Z字母检 ...
- android自定义View之NotePad出鞘记
现在我们的手机上基本都会有一个记事本,用起来倒也还算方便,记事本这种东东,如果我想要自己实现,该怎么做呢?今天我们就通过自定义View的方式来自定义一个记事本.OK,废话不多说,先来看看效果图. 整个 ...
随机推荐
- 基于Keras的imdb数据集电影评论情感二分类
IMDB数据集下载速度慢,可以在我的repo库中找到下载,下载后放到~/.keras/datasets/目录下,即可正常运行.)中找到下载,下载后放到~/.keras/datasets/目录下,即可正 ...
- 自定义equals
@Overridepublic boolean equals(Object o) { if (o == null || getClass() != o.getClass()) { return fal ...
- 奇技淫巧之 unordered_map
哇,虽然我不知道到为什么这个东西比map快(快了一倍),注意unordered_map要在c++11以上的编译环境下才能用,如c++11,GNU G++11 5.1.0,GNU G++14 .
- 工作总结 vue 城会玩
用了vue2.0,vuex, vue-router等较新的技术,完成了城会玩这个项目,过程中发现自己许多不足,也得到很多人帮助,特别是有些困难的技术点.现在项目上线了,在此做一个整理和总结. 1.ke ...
- Eclipse实用插件
Eclipse实用插件 安装:Help - Eclipse Marketplace 查看图片:QuickImage 主题:Darkest Dark 代码风格:https://blog.csdn.net ...
- css学习杂记
1.css中的&语法 &是sass的语法,代表上一级选择器. 例如: .el-row { margin-bottom: 20px; &:last-child { margin- ...
- mongodb主从以及auth主从 配置详解
1.主服务器配置 #auth = true dbpath = /data/mongodb/db logpath = /data/mongodb/log/mongodb.log port = ...
- 5. 使用Flask蓝图(blueprint)
一直到现在都没有怎么写代码,可能更得比较慢. 作业回顾 先来看一下文章4的作业吧,使用logbook的时候,遇到了时区不对的情况.那么我们怎么去解决这个问题呢? 实际上logbook默认采用的是世界标 ...
- maven scope属性值设置含义
1.枚举各个属性值的含义 compile,缺省值,适用于所有阶段,会打包进项目. provided,类似compile,期望JDK.容器或使用者会提供这个依赖. runtime,只在运行时使用,如JD ...
- HIVE函数的UDF、UDAF、UDTF
一.词义解析 UDF(User-Defined-Function) 一进一出 UDAF(User- Defined Aggregation Funcation) 多进一出 (聚合函数,MR) UDTF ...