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,废话不多说,先来看看效果图. 整个 ...
随机推荐
- ubuntu 装 mysql
sudo apt-get install mysql-server mysql-client
- 11-[CSS]-标准文档流,display,浮动,清除浮动,overflow
1.标准文档流 <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...
- 01- ajax, 登录验证,json数据,文件上传
1.ajax简介 1.向服务器发送请求的途径 # 向服务器发送请求的途径 1. 浏览器地址栏,默认get请求 2. form表单: get请求 post请求 3. a标签,默认get请求 4. Aja ...
- Flutter - Finished with error: FormatException: Bad UTF-8 encoding 0xc3 (at offset 169)
方案1: 更改项目的Encoding方式 File -> Settings -> Editor, choose "File Encodings", change Pr ...
- JavaScript 的HTML转义方法 html_encode 和 html_decode
此方法用来将用户输入内容中的尖括号.引号等进行转义
- How to: Display a Non-Persistent Object's List View from the Navigation
This example demonstrates how to display a non-persistent object's List View when a navigation item ...
- yum 出现error: db5 error
yum 安装k8s的过程中用了 Ctrl+ z, 然后yum 再也不能使用了: Error: rpmdb open failed 解决方法: rpm --rebuilddb yum clean all ...
- 对最近java基础学习的一次小结
开头想了3分钟,不知道起什么名字好,首先内容有点泛,但也都是基础知识. 对之前所学的java基础知识做了个小结,因为我是跟着网上找的黑马的基础视频看跟着学的,10天的课程硬生生给我看了这么久,也是佛了 ...
- 在server 2003中搭建域服务(Http NTLM 代理)
在server 2003中搭建域服务(Http NTLM 代理) 在windows server 2003 X64中搭建域服务的操作. 可参考百度经验:http://www.cnblogs.com/z ...
- C++构造函数和析构函数什么情况下会用
析构函数: 1. 对象生命周期结束,被销毁时: 2. delete 指向对象的指针时: 3. delete 指向基类对象的指针时,其析构函数是虚函数: 4. 在嵌套关系中,对象A是对象B的成员,当对象 ...