仿QQ计步器效果的实现

仿QQ计步器效果的实现,第1张

概述效果展示仿QQ计步器的效果展示思路分析1、固定不动蓝色的大圆弧colorborderWidth2、可以变化的小圆弧(红色)colorborderWidth3、中间的步数文字colortextSize这里,因为内外圆弧宽度宽度一样,所以,可统一命名为borderWidth开始码字第一步:自定义控件类的 效果展示

仿QQ计步器的效果展示
思路分析

1、固定不动蓝色的大圆弧 color borderWIDth

2、可以变化的小圆弧(红色) color borderWIDth

3、中间的步数文字 color textSize

这里,因为内外圆弧宽度宽度一样,所以,可统一命名为 borderWIDth

开始码字

第一步:自定义控件类的创建 继承自 VIEw

 

第二步:自定义属性文件的创建,及内容的编写

<?xml version="1.0" enCoding="utf-8"?><resources>    <declare-styleable name="QQStepVIEw">        <attr name="outercolor" format="color"/>        <attr name="innercolor" format="color"/>        <attr name="borderWIDth" format="dimension"/>        <attr name="stepTextSize" format="dimension"/>        <attr name="stepTextcolor" format="color"/>    </declare-styleable></resources>

如何创建自定义属性文件,我前面有讲解 ,不懂得可自行复习

第三步:在布局文件中应用

<?xml version="1.0" enCoding="utf-8"?><relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"    xmlns:app="http://schemas.androID.com/apk/res-auto"    xmlns:tools="http://schemas.androID.com/tools"    androID:layout_wIDth="match_parent"    androID:layout_height="match_parent"    tools:context=".MainActivity">    <com.example.qqstepvIEw.QQStepVIEw        androID:ID="@+ID/step_vIEw"        androID:background="@color/colorAccent"        androID:layout_wIDth="match_parent"        androID:layout_height="match_parent"        app:outercolor="@color/colorPrimaryDark"        app:innercolor="#f00"        app:borderWIDth="20dp"        app:stepTextcolor="#f00"        app:stepTextSize="50sp"/></relativeLayout>

第四步:在自定义组件类 中 获取自定义属性 并编写相关方法

package com.example.qqstepvIEw;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.vIEw.VIEw;import androIDx.annotation.Nullable;public class QQStepVIEw extends VIEw {    private int mOutercolor = color.parsecolor("#3700B3");    private int mInnercolor = color.parsecolor("#ff0000");    private int mborderWIDth = 20; //20px    private int mStepTextSize = 14; //14px    private int mStepTextcolor;    private Paint mOutPaint,mInnerPaint,mTextPaint;    private Context mContext;    //总共的,当前的步数    private int mStepMax = 100;    private int mCurrentStep = 50;    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);        this.mContext = context;        //1、分析效果 2、确定自定义属性 编写attrs.xml 3、在布局中使用 4、在自定义view中获取自定义属性        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.QQStepVIEw);        mOutercolor = typedArray.getcolor(R.styleable.QQStepVIEw_outercolor, mOutercolor);        mInnercolor = typedArray.getcolor(R.styleable.QQStepVIEw_innercolor, mInnercolor);        mborderWIDth = (int) typedArray.getDimension(R.styleable.QQStepVIEw_borderWIDth,mborderWIDth);        mStepTextSize = typedArray.getDimensionPixelSize(R.styleable.QQStepVIEw_stepTextSize,mStepTextSize);        mStepTextcolor = typedArray.getcolor(R.styleable.QQStepVIEw_stepTextcolor,mStepTextcolor);        typedArray.recycle();        //初始化数据        initData();        //5、onMeasure()        //6、画外圆弧 内圆弧 文字        //7、其他    }    private voID initData() {        mOutPaint = new Paint();        mOutPaint.setAntiAlias(true);        mOutPaint.setstrokeWIDth(mborderWIDth);        mOutPaint.setcolor(mOutercolor);        mOutPaint.setStyle(Paint.Style.stroke);        mOutPaint.setstrokeCap(Paint.Cap.ROUND);        mInnerPaint = new Paint();        mInnerPaint.setAntiAlias(true);        mInnerPaint.setstrokeWIDth(mborderWIDth);        mInnerPaint.setcolor(mInnercolor);        mInnerPaint.setStyle(Paint.Style.stroke);        mInnerPaint.setstrokeCap(Paint.Cap.ROUND);        mTextPaint = new Paint();        mTextPaint.setAntiAlias(true);        mTextPaint.setTextSize(mStepTextSize);        mTextPaint.setcolor(mStepTextcolor);    }    //5、onMeasure()    @OverrIDe    protected voID onMeasure(int wIDthMeasureSpec, int heightmeasureSpec) {        super.onMeasure(wIDthMeasureSpec, heightmeasureSpec);        //调用者在布局文件中可能  wrap_content 宽度高度不一致        int wIDth = MeasureSpec.getSize(wIDthMeasureSpec) + getpaddingleft() + getpaddingRight();        int height = MeasureSpec.getSize(heightmeasureSpec) + getpaddingtop() +getpaddingBottom();        int wIDthMode = MeasureSpec.getMode(wIDthMeasureSpec);        int heightmode = MeasureSpec.getMode(heightmeasureSpec);        if (wIDthMode == MeasureSpec.AT_MOST){        }        if (heightmode == MeasureSpec.AT_MOST){        }        setMeasuredDimension(wIDth>height?height:wIDth,wIDth>height?height:wIDth);    }    //6、画外圆弧 内圆弧 文字    @OverrIDe    protected voID onDraw(Canvas canvas) {        super.onDraw(canvas);        int center = getWIDth()/2;        int radius = getWIDth()/2 - mborderWIDth/2;        //6.1 画外圆弧        RectF rectF = new RectF(center - radius ,                center - radius ,                center + radius ,                center + radius ); //第一种写法        //RectF rectF = new RectF(mborderWIDth/2,mborderWIDth/2,getWIDth() - mborderWIDth/2,getWIDth() - mborderWIDth/2); //第二种写法        canvas.drawArc(rectF,135,270,false,mOutPaint);        //6.2 画内圆弧 怎么画肯定不能写死  百分比 是使用者设置的 从外面传        System.out.println("mCurrentStep:"+mCurrentStep+"mStepMax:"+mStepMax);        if (mStepMax == 0)return;        float sweepAngle = (float)mCurrentStep/mStepMax;        canvas.drawArc(rectF,135,sweepAngle*270,false,mInnerPaint);        //6.3 画文字        String stepText = mCurrentStep + "";        //基线        Paint.FontMetricsInt FontMetricsInt = mTextPaint.getFontMetricsInt();        int dy = (FontMetricsInt.bottom - FontMetricsInt.top)/2 - FontMetricsInt.bottom;        int baseline = getHeight()/2 + dy;        //文字起始位置        Rect textBounds = new Rect();        mTextPaint.getTextBounds(stepText,0,stepText.length(),textBounds);        int dx = textBounds.wIDth();        float x = getWIDth()/2 - dx/2; //dx表示文字宽度        canvas.drawText(stepText,x,baseline,mTextPaint);    }    //7,其他,写几个方法动起来    public synchronized voID  setStepMax (int stepMax){        this.mStepMax = stepMax;    }    public synchronized voID  setCurrentStep (int currentStep){        this.mCurrentStep = currentStep;        //不断绘制        invalIDate();    }}

里面有一些冗余代码,比如初始化画笔可以封装,我就不在此优化了

第五步:在使用了自定义组件的 类中 调用

package com.example.qqstepvIEw;import androIDx.appcompat.app.AppCompatActivity;import androID.animation.ObjectAnimator;import androID.animation.ValueAnimator;import androID.os.Bundle;import androID.vIEw.VIEw;import androID.vIEw.animation.AccelerateDecelerateInterpolator;import androID.vIEw.animation.BounceInterpolator;import androID.vIEw.animation.DecelerateInterpolator;public class MainActivity extends AppCompatActivity {    @OverrIDe    protected voID onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentVIEw(R.layout.activity_main);        final QQStepVIEw step_vIEw = findVIEwByID(R.ID.step_vIEw);        step_vIEw.setStepMax(4000);        //值动画        ValueAnimator valueAnimator = ObjectAnimator.offloat(0, 3000);        valueAnimator.setDuration(1000);        valueAnimator.setInterpolator(new DecelerateInterpolator());        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @OverrIDe            public voID onAnimationUpdate(ValueAnimator animation) {                float currentStep = (float) animation.getAnimatedValue();                step_vIEw.setCurrentStep((int) currentStep);            }        });        valueAnimator.start();    }}

源码连接:QQStepView

总结

以上是内存溢出为你收集整理的仿QQ计步器效果的实现全部内容,希望文章能够帮你解决仿QQ计步器效果的实现所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1041444.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存