美文网首页
实现一个简单的计步器功能

实现一个简单的计步器功能

作者: 乌托邦式的爱情 | 来源:发表于2021-07-09 18:12 被阅读0次

废话不多说,直接上效果图


1.自定义步数效果图.gif

相信这个效果大家都不会陌生,作为自定义View的开篇章节,我们先牛刀小试一把。一般情况下,当我们拿到美工或者产品需要我们实现的效果图时,不要急于去写代码,而是应该好好去分析一下到底该如何去实现这个功能,就这个功能而言,我给它拆分为几个部分:

1.底部的总步数条(固定)
2.加载的步数条(变动)
3.对应显示的文字步数

接下来我们就一步一步来看到底怎么做:
(1)首先我们的底部的总步数条颜色不能写死,加载的步数条颜色也不能写死还有步数条宽度的大小也不能写死,除此之外显示的文字步数(字体大小、颜色)也不能写死,所以,我们需要通过自定义属性的方式让用户自己设定。

    <!-- 计步器的自定义样式 -->
    <declare-styleable name="StepView">
        <attr name="step_view_fix_progress_color" format="color"/>
        <attr name="step_view_current_progress_color" format="color"/>
        <attr name="step_view_progress_size" format="dimension"/>
        <attr name="step_view_text_color" format="color"/>
        <attr name="step_view_text_size" format="dimension"/>
    </declare-styleable>

(2)获取自定义样式之后就需要给我们的每个部分设置画笔了

    // 画文字的画笔
    private Paint mTextPaint;

    // 设置最大的步数
    private int mMaxStep;

    // 设置当前的步数
    private int mCurrentStep;


    public StepView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        // 省略代码

        // 设置画笔
        mFixProgressPaint = initPaint(mFixedProgressColor);
        mCurrentProgressPaint = initPaint(mCurrentProgressColor);

        mTextPaint = new Paint();
        // 抗锯齿
        mTextPaint.setAntiAlias(true);
        // 防抖动
        mTextPaint.setDither(true);
        // 设置画笔的颜色
        mTextPaint.setColor(mTextColor);
        // 设置画笔的大小
        mTextPaint.setTextSize(mTextSize);

    }

    private Paint initPaint(int color) {
        Paint paint = new Paint();
        // 抗锯齿
        paint.setAntiAlias(true);
        // 防抖动
        paint.setDither(true);
        // 设置画笔的颜色
        paint.setColor(color);
        // 设置画笔的大小
        paint.setStrokeWidth(mProgressSize);
        // 设置画笔的样式
        paint.setStyle(Paint.Style.STROKE);
        // 设置画笔的端的样式
        paint.setStrokeCap(Paint.Cap.ROUND);
        return paint;
    }

(3)在我们的onDraw()方法里面去画了

  @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 1.画固定的圆弧
        RectF rectF = new RectF(mProgressSize / 2, mProgressSize / 2, getWidth() - mProgressSize / 2, getHeight() - mProgressSize / 2);
        canvas.drawArc(rectF, 135, 270, false, mFixProgressPaint);
        // 2.画非固定圆弧
        if (mCurrentStep < 1) {
            return;
        }
        canvas.drawArc(rectF, 135, (float) mCurrentStep / mMaxStep * 270, false, mCurrentProgressPaint);
        // 3.画文字
        String value = String.valueOf(mCurrentStep);
        // 3.1计算文字的宽度和高度
        Rect rect = new Rect();
        mTextPaint.getTextBounds(value, 0, value.length(), rect);
        float x = getWidth() / 2 - rect.width() / 2;
        // 计算基线
        Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
        float y = getHeight() / 2 + (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;
        canvas.drawText(value, x, y, mTextPaint);
    }

(4)配合我们的属性动画实现动态效果

private fun startStep(){
        step_view.setMaxStep(4000)
        val valueAnimation = ObjectAnimator.ofInt(0,3000)
        valueAnimation.duration = 1000
        valueAnimation.addUpdateListener {
            val value:Int = it.animatedValue as Int
            step_view.setCurrentStep(value)
        }
        valueAnimation.start()
    }

最后贴上完整代码如下:

public class StepView extends View {

    // 总步数对应的颜色
    private int mFixedProgressColor = Color.GRAY;

    // 当前步数对应的颜色
    private int mCurrentProgressColor = Color.YELLOW;

    // 进度条对应的大小
    private int mProgressSize = 5;

    // 字体对应的颜色
    private int mTextColor = Color.YELLOW;

    // 字体对应的大小(像素)
    private int mTextSize = 15;

    // 画总步数的画笔
    private Paint mFixProgressPaint;

    // 画变动步数的画笔
    private Paint mCurrentProgressPaint;

    // 画文字的画笔
    private Paint mTextPaint;

    // 设置最大的步数
    private int mMaxStep;

    // 设置当前的步数
    private int mCurrentStep;


    public StepView(Context context) {
        this(context, null);
    }

    public StepView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public StepView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // 先理清一下思路,再来进行编码
        // 整个功能分为3个部分,底部的总步数条(固定)、加载的步数条(变动)、对应显示的文字步数
        // 1.获取自定义属性
        // <1> 底部的总步数条颜色
        // <2> 加载的步数条颜色
        // <3> 步数条宽度
        // <4> 显示的文字步数(字体大小、颜色)
        // 2.通过draw()方法绘制静态效果
        // 3.通过属性动画来实现动态加载

        // 1.获取自定义属性
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.StepView);
        mFixedProgressColor = array.getColor(R.styleable.StepView_step_view_fix_progress_color, mFixedProgressColor);
        mCurrentProgressColor = array.getColor(R.styleable.StepView_step_view_current_progress_color, mCurrentProgressColor);
        mProgressSize = array.getDimensionPixelSize(R.styleable.StepView_step_view_progress_size, mProgressSize);
        mTextColor = array.getColor(R.styleable.StepView_step_view_text_color, mTextColor);
        mTextSize = array.getDimensionPixelSize(R.styleable.StepView_step_view_text_size, mTextSize);
        array.recycle();

        // 设置画笔
        mFixProgressPaint = initPaint(mFixedProgressColor);
        mCurrentProgressPaint = initPaint(mCurrentProgressColor);

        mTextPaint = new Paint();
        // 抗锯齿
        mTextPaint.setAntiAlias(true);
        // 防抖动
        mTextPaint.setDither(true);
        // 设置画笔的颜色
        mTextPaint.setColor(mTextColor);
        // 设置画笔的大小
        mTextPaint.setTextSize(mTextSize);

    }

    private Paint initPaint(int color) {
        Paint paint = new Paint();
        // 抗锯齿
        paint.setAntiAlias(true);
        // 防抖动
        paint.setDither(true);
        // 设置画笔的颜色
        paint.setColor(color);
        // 设置画笔的大小
        paint.setStrokeWidth(mProgressSize);
        // 设置画笔的样式
        paint.setStyle(Paint.Style.STROKE);
        // 设置画笔的端的样式
        paint.setStrokeCap(Paint.Cap.ROUND);
        return paint;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 1.画固定的圆弧
        RectF rectF = new RectF(mProgressSize / 2, mProgressSize / 2, getWidth() - mProgressSize / 2, getHeight() - mProgressSize / 2);
        canvas.drawArc(rectF, 135, 270, false, mFixProgressPaint);
        // 2.画非固定圆
        if (mCurrentStep < 1) {
            return;
        }
        canvas.drawArc(rectF, 135, (float) mCurrentStep / mMaxStep * 270, false, mCurrentProgressPaint);
        // 3.画文字
        String value = String.valueOf(mCurrentStep);
        // 3.1计算文字的宽度和高度
        Rect rect = new Rect();
        mTextPaint.getTextBounds(value, 0, value.length(), rect);
        float x = getWidth() / 2 - rect.width() / 2;
        // 计算基线
        Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
        float y = getHeight() / 2 + (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;
        canvas.drawText(value, x, y, mTextPaint);
    }

    /**
     * 设置最大步数值
     *
     * @param maxStep 最大步数值
     */
    public void setMaxStep(int maxStep) {
        this.mMaxStep = maxStep;
    }

    /**
     * 设置当前步数值
     *
     * @param currentStep 当前步数值
     */
    public void setCurrentStep(int currentStep) {
        this.mCurrentStep = currentStep;
        invalidate();
    }
}

相关文章

  • 实现一个简单的计步器功能

    废话不多说,直接上效果图 相信这个效果大家都不会陌生,作为自定义View的开篇章节,我们先牛刀小试一把。一般情况下...

  • iOS计步器实现

    前几天写一个关于养生和医疗的一个项目,要写一个类似微信运动的计步器功能,只好先去研究一下计步器功能实现。 之前在我...

  • iOS 实现计步器功能

    现在越来越多的人关注运动和健康,iOS系统也在很早的时候就自带了健康APP,下面详细描述一下在我们开发中,怎么实现...

  • 计步器UI实现

    UI说明: 1.浅色的表示总共是100%2.深蓝色的表示执行了75%3.数字描述4.单位描述 技术知识: 在Can...

  • 超简单实现iOS列表的索引功能

    超简单实现iOS列表的索引功能 超简单实现iOS列表的索引功能

  • 探索iOS计步器功能

    我的一个朋友是从事外出销售工作,老板不但要看他每天的业绩,也会去关注他每天在某个APP的行走步数。你应该知道的,业...

  • 2 并发编程初体验

    1️⃣前言 在开始真正的讲解以前,我们实现一个简单的场景-实现一个计数功能 计数功能 : CountExample...

  • H36-把 MVC 的 VC 加到简历里

    模块化 简单来说就是将功能不同的代码分开来,实现a功能的代码一个文件,实现b功能的代码一个文件阮一峰 模块就是实现...

  • 分页组件的简单实现(初稿)

    分页功能是后台管理系统中很常见的一个功能,今天我们就来看下如何实现一个简单的分页组件。 初步实现 首先从最简单的情...

  • 基于三轴传感器的计步器代码实现-iOS

    原有iOS计步器采用系统框架swift语言调用 改为三轴传感器的计步器实现 开启陀螺仪采集三轴数据 计步核心 波峰...

网友评论

      本文标题:实现一个简单的计步器功能

      本文链接:https://www.haomeiwen.com/subject/pbnfpltx.html