1.效果

2.实现

2.1自定义属性

在res/values 文件夹中新建xx.xml,内容如下

<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--自定义QQ步数控件-->
<declare-styleable name="QQStepView">
<!--外圈的颜色-->
<attr name="outerColor" format="color" />
<!--内圈的额颜色-->
<attr name="innerColor" format="color" />
<!--外圈的宽度-->
<attr name="outerWidth" format="dimension" />
<!--内圈的宽度-->
<attr name="innerWidth" format="dimension" />
<!--最大步数-->
<attr name="stepMax" format="integer" />
<!--中间文字的大小-->
<attr name="stepTextSize" format="dimension" />
<!--中间文字的颜色-->
<attr name="stepTextColor" format="color" />
</declare-styleable>
</resources>

2.2继承view实现java代码

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View; import androidx.annotation.Nullable; /**
* Created by DongKing on 2020/11/6
* Version 1.0
* Describe:qq步数
*/
class QQStepView extends View {
private int mStepMax = 10000;//默认最大值
private int mCurrentStep = 0;//当前值
private int mOuterColor = Color.RED;
private int mInnerColor = Color.BLUE;
private int mOuterWidth = 30;
private int mInnerWidth = 18;
private int mStepTextSize = 18;
private int mStepTextColor = Color.LTGRAY; Paint mInnerPaint;//画内圆的画笔
Paint mOuterPaint;//画外圆的画笔
Paint mTextPaint;//画文字的画笔 public QQStepView(Context context) {
this(context, null);
} public QQStepView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
} public QQStepView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//获取自定义属性
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.QQStepView);
mOuterColor = array.getColor(R.styleable.QQStepView_outerColor, mOuterColor);
mInnerColor = array.getColor(R.styleable.QQStepView_innerColor, mInnerColor);
mOuterWidth = (int) array.getDimension(R.styleable.QQStepView_outerWidth, mOuterWidth);
mInnerWidth = (int) array.getDimension(R.styleable.QQStepView_innerWidth, mInnerWidth);
mStepTextSize = array.getDimensionPixelSize(R.styleable.QQStepView_stepTextSize, mStepTextSize);
mStepTextColor = array.getColor(R.styleable.QQStepView_stepTextColor, mStepTextColor);
mStepMax = array.getInt(R.styleable.QQStepView_stepMax, mStepMax); array.recycle();
//初始化画笔
mOuterPaint = new Paint();
mOuterPaint.setAntiAlias(true);
mOuterPaint.setStrokeCap(Paint.Cap.ROUND);
mOuterPaint.setColor(mOuterColor);
mOuterPaint.setStrokeWidth(mOuterWidth);
mOuterPaint.setStyle(Paint.Style.STROKE);
mInnerPaint = new Paint();
mInnerPaint.setAntiAlias(true);
mInnerPaint.setStrokeCap(Paint.Cap.ROUND);
mInnerPaint.setColor(mInnerColor);
mInnerPaint.setStrokeWidth(mInnerWidth);
mInnerPaint.setStyle(Paint.Style.STROKE);
mTextPaint = new Paint();
mTextPaint.setAntiAlias(true);
mTextPaint.setTextSize(mStepTextSize);
mTextPaint.setColor(mStepTextColor);
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec); //保证是一个正方形
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 = center - (mOuterWidth > mInnerWidth ? mOuterWidth : mInnerWidth) / 2;
RectF rectF = new RectF(center - radius, center - radius, center + radius, center + radius);
//1.画里面的圆弧
canvas.drawArc(rectF, 135, 270, false, mInnerPaint);
//2.画外面的圆弧
if (mStepMax == 0) {
return;
} float sweepAngle = (float) mCurrentStep / mStepMax * 270;
canvas.drawArc(rectF, 135, sweepAngle, false, mOuterPaint);
//3.画文字
Rect rect = new Rect();
String stepText = mCurrentStep + "";
mTextPaint.getTextBounds(stepText, 0, stepText.length(), rect);
int dx = getWidth() / 2 - rect.width() / 2; Paint.FontMetricsInt fontMetricsInt = mTextPaint.getFontMetricsInt();
int dy = (fontMetricsInt.bottom - fontMetricsInt.top) / 2 - fontMetricsInt.bottom;
int baseLine = getHeight() / 2 + dy; canvas.drawText(stepText, dx, baseLine, mTextPaint);
} public synchronized void setCurrentStep(int currentStep) {
this.mCurrentStep = currentStep;
invalidate();
}
}

3.使用

3.1 布局文件中

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myapp="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.nb.customview.QQStepView
android:id="@+id/qq_step_view"
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_gravity="center_horizontal"
myapp:innerColor="@android:color/holo_green_dark"
myapp:innerWidth="10dp"
myapp:outerColor="@android:color/holo_blue_light"
myapp:outerWidth="12dp"
myapp:stepMax="10000"
myapp:stepTextColor="@android:color/holo_blue_light"
myapp:stepTextSize="30sp" />
</LinearLayout>

3.2 activity中

public class MainActivity extends AppCompatActivity {
QQStepView mQqStepView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mQqStepView = findViewById(R.id.qq_step_view);
init(); } private void init() {
ValueAnimator valueAnimator = ObjectAnimator.ofInt(0, 8000);
valueAnimator.setDuration(3000);
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.addUpdateListener(animation -> {
int currentStep = (int) animation.getAnimatedValue();
mQqStepView.setCurrentStep(currentStep);
});
valueAnimator.start();
} }

2.自定义view-QQ运动步数的更多相关文章

  1. QQ运动步数&自定义ProgressBar

    效果如下 gif图展示效果不好,实际体验无卡顿 1.自定义属性 早Values目录下New-values resource file,命名为attrs.xml(命名随意,但规范命名为attrs.xml ...

  2. Android自定义View——QQ音乐中圆形旋转碟子

    1.在onMeasure中测量整个View的宽和高后,设置宽高 2.获取我们res的图片资源后,在ondraw方法中进行绘制圆形图片 3.通过Handler发送Runnable在主线程中更新UI,达到 ...

  3. Android自定义View实现仿QQ实现运动步数效果

    效果图: 1.attrs.xml中 <declare-styleable name="QQStepView"> <attr name="outerCol ...

  4. Android 自定义View实现QQ运动积分抽奖转盘

    因为偶尔关注QQ运动, 看到QQ运动的积分抽奖界面比较有意思,所以就尝试用自定义View实现了下,原本想通过开发者选项查看下界面的一些信息,后来发现积分抽奖界面是在WebView中展示的,应该是在H5 ...

  5. 手把手教你修改iOS版QQ的运动步数

    手把手教你修改iOS版QQ的运动步数 现在很多软件都加上了运动模块,比如QQ和微信,而且还有排行榜,可以和好友比较谁的运动步数多,任何东西只要添加了比较功能,就变得不一样了.今天教大家用代码去修改QQ ...

  6. 安卓自定义View实现图片上传进度显示(仿QQ)

    首先看下我们想要实现的效果如下图(qq聊天中发送图片时的效果): 再看下图我们实现的效果: 实现原理很简单,首先我们上传图片时需要一个进度值progress,这个不管是自己写的上传的方法还是使用第三方 ...

  7. wing带你玩转自定义view系列(2) 简单模仿qq未读消息去除效果

    上一篇介绍了贝塞尔曲线的简单应用 仿360内存清理效果 这一篇带来一个  两条贝塞尔曲线的应用 : 仿qq未读消息去除效果. 转载请注明出处:http://blog.csdn.net/wingicho ...

  8. 自定义View,随着手指运动的小球

    这个实例是自定的view的初步介绍,要设计的是一个随着手指运动的小球.原理是随时获取手指的坐标,然后在这个坐标上面实时改变自定义view的坐标.这个view仅仅是画了一个圆形而已. 自定义的view ...

  9. 2017了,回家前 "年末" 分享:下雨,飘雪,红包雨,碰撞球,自定义View

    (本博客为原创:http://www.cnblogs.com/linguanh/) 目录: 效果展示 感想 代码拆解 开源地址 效果展示 有没有兴趣继续看下去,直接看下"颜值"是第 ...

  10. 高阶自定义View --- 粒子变幻、隧道散列、组合文字

    高阶自定义View --- 粒子变幻.隧道散列.组合文字 作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:h ...

随机推荐

  1. Java线程池一:线程基础

    最近精读Netty源码,读到NioEventLoop部分的时候,发现对Java线程&线程池有些概念还有困惑, 所以深入总结一下 线程创建 Java线程创建主要有三种方式:继承Thread类.实 ...

  2. TkMybatis 是什么?

    一.TkMybatis Tkmybatis 是基于 Mybatis 框架开发的一个工具,通过调用它提供的方法实现对单表的数据操作,不需要写任何 sql 语句,这极大地提高了项目开发效率. 二.怎么用? ...

  3. Plant Leaves Classification植物叶子分类:基于孪生网络的小样本学习方法

    目录 Abstract Introduction PROPOSED CNN STRUCTURE INITIAL CNN ANALYSIS EXPERIMENTAL STRUCTURE AND ALGO ...

  4. 关于Django的序列化问题。serializers

    在DRF框架里,ModelSerializers是一个重要的组件.大大的帮组我们节省了数据序列化的过程,真的可以说是良心产品.接手的这个项目用的Django,前人的代码都是手动序列化的,为了保证风格的 ...

  5. Python中的文档字符串作用

    文档字符串是使用一对三个单引号 ''' 或者一对三个双引号 """来包围且没有赋值给变量的一段文字说明(如果是单行且本身不含引号,也可以是单引号和双引号), 它在代码执行 ...

  6. 为什么Python中sort方法和sorted函数调用废弃使用cmp参数

    Python中sort方法和sorted函数老猿在前面一些章节介绍过,具体语法及含义在此不再展开说明,但老猿在前面学习相关内容时,只使用了简单的案例,对这两个方法的key参数没有深入研究,总以为就是以 ...

  7. Python中自定义类未定义__lt__方法使用sort/sorted排序会怎么处理?

    在<第8.23节 Python中使用sort/sorted排序与"富比较"方法的关系分析>中介绍了排序方法sort和函数sorted在没有提供key参数的情况下默认调用 ...

  8. 第十五章、Model/View架构中Item Views部件的父类

    老猿Python博文目录 老猿Python博客地址 引言:本章早就写好了,其简版<第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详 ...

  9. PyQt及PyCharm学习中遇到的问题

    在PyQt及PyCharm学习过程中,老猿遇到了如下问题: 问题: 刚安装的PyCharm执行代码报"ModuleNotFoundError: No module named XXXX&qu ...

  10. CNVD漏洞证书(2)

    第二张CNVD的原创漏洞证书. 关于证书申请可以看我之前写的这篇博客: https://www.cnblogs.com/Cl0ud/p/12720413.html 继续加油