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计步器效果的实现所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)