当前位置: 首页 > news >正文

专门做图片的网站cms搭建网站是什么意思

专门做图片的网站cms,搭建网站是什么意思,推广网站制作,杭州网站优化效果很多场景下都用到这种进度条#xff0c;有的还带动画效果#xff0c; 今天我也来写一个。 写之前先拆解下它的组成#xff1a; 底层圆形上层弧形中间文字 那我们要做的就是#xff1a; 绘制底层圆形#xff1b;在同位置绘制上层弧形#xff0c;但颜色不同#xff…很多场景下都用到这种进度条有的还带动画效果 今天我也来写一个。 写之前先拆解下它的组成 底层圆形上层弧形中间文字 那我们要做的就是 绘制底层圆形在同位置绘制上层弧形但颜色不同在中心点绘制文本显示进度。 按照这个目标学习下自定义View的流程。 1.基础 新建一个类继承 View 重写构造函数如 package com.test.luodemo.customerview;import android.content.Context; import android.util.AttributeSet; import android.view.View;import androidx.annotation.Nullable;public class CircleProgressBar extends View {public CircleProgressBar(Context context) {super(context);}public CircleProgressBar(Context context, Nullable AttributeSet attrs) {super(context, attrs);}public CircleProgressBar(Context context, Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);} }在 xml 中使用LinearLayout 加了背景颜色方便看出所在位置。 LinearLayoutandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgroundcolor/purple_200com.test.luodemo.customerview.CircleProgressBarandroid:layout_width300dpandroid:layout_height300dp//LinearLayout此时运行是没效果的因为这个View还没有绘制啥也没有。 2.绘制底层圆形 初始化3个图形的画笔 底层圆形和上层弧形的画笔宽度一致、颜色不一致方便区分 重写 onDraw(Canvas canvas) 方法用 canvas.drawCircle 绘制底层圆形 package com.test.luodemo.customerview;import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.view.View;import androidx.annotation.Nullable;public class CircleProgressBar extends View {private Paint paintCircleBottom new Paint();private Paint paintArcTop new Paint();private Paint paintText new Paint();public CircleProgressBar(Context context) {super(context);init();}public CircleProgressBar(Context context, Nullable AttributeSet attrs) {super(context, attrs);init();}public CircleProgressBar(Context context, Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}private void init(){//初始化文本的画笔paintText.setFlags(Paint.ANTI_ALIAS_FLAG);paintText.setColor(Color.BLACK);paintText.setTextAlign(Paint.Align.CENTER);paintText.setTextSize(80f);//初始化底层圆形的画笔paintCircleBottom.setFlags(Paint.ANTI_ALIAS_FLAG);paintCircleBottom.setColor(Color.LTGRAY);paintCircleBottom.setStrokeWidth(10f);paintCircleBottom.setStrokeCap(Paint.Cap.ROUND);paintCircleBottom.setStyle(Paint.Style.STROKE);//初始化弧形的画笔paintArcTop.setFlags(Paint.ANTI_ALIAS_FLAG);paintArcTop.setColor(Color.MAGENTA);paintArcTop.setStrokeWidth(10f);paintArcTop.setStrokeCap(Paint.Cap.ROUND);paintArcTop.setStyle(Paint.Style.STROKE);}Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//绘制底层圆形canvas.drawCircle(300, 300, 200, paintCircleBottom);} } 效果 3.绘制上层弧形 在之前的基础上绘制上层弧形弧形的中心和圆心一致。 用 canvas.drawArc 绘制弧形。这里直接指定绘制的角度是 90° 后续会动态指定。 Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//绘制底层圆形canvas.drawCircle( 300, 300, 200, paintCircleBottom);//绘制上层弧形,从顶部开始顺时针走90°_angle 90;canvas.drawArc(100,100,500,500,270, _angle,false, paintArcTop);}效果 4.绘制文本 用 canvas.drawText 绘制文本 使用 DecimalFormat 格式化输入保留小数点后两位如果小数点后两位都是0则不显示小数点后两位。 Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//绘制底层圆形canvas.drawCircle(300, 300, 200, paintCircleBottom);//绘制上层弧形,从顶部开始顺时针走90°_angle 90;canvas.drawArc(100,100,500,500,270, _angle,false, paintArcTop);//绘制文本DecimalFormat dt new DecimalFormat(0.##);canvas.drawText(dt.format(100 * _angle/360)%, 300 , 300, paintText);}效果 可以看到文本虽然居中但是文本是显示在中心线上 期望结果是文本的水平中心线和圆心重合改为 //绘制文本,文字中心和圆心保持一致Paint.FontMetrics fontMetrics paintText.getFontMetrics();float distance (fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom;float baseline 300 distance;canvas.drawText(dt.format(100 * _angle/360)%, 300, baseline, paintText);//文字中心和圆心一致 效果复合预期。 5.添加动画 创建一个设置进度的接口供外部调用。 使用 ValueAnimator 监听动画过程然后逐渐刷新角度值。使用 AccelerateInterpolator 插值器动画速度开始慢、逐渐加速。 Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//绘制底层圆形canvas.drawCircle(300, 300, 200, paintCircleBottom);//绘制上层弧形,从顶部开始顺时针走90°canvas.drawArc(100,100,500,500,270, _angle,false, paintArcTop);//绘制文本,文字中心和圆心保持一致DecimalFormat dt new DecimalFormat(0.##);Paint.FontMetrics fontMetrics paintText.getFontMetrics();float distance (fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom;float baseline 300 distance;canvas.drawText(dt.format(100 * _angle/360)%, 300, baseline, paintText);//文字中心和圆心一致}/*** 设置进度展现动画* */public void setProgress(int progress){ValueAnimator animator ValueAnimator.ofFloat(0,100f);animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {Overridepublic void onAnimationUpdate(ValueAnimator animation) {float cur (float) animation.getAnimatedValue();_angle cur/100 * 360 * progress/100;invalidate(); //刷新 View}});animator.setDuration(3000);animator.setInterpolator(new AccelerateInterpolator());animator.start();}注意要去掉 3.绘制上层弧形 中固定90°的逻辑。 外部调用 CircleProgressBar mCircleProgressBar1 (CircleProgressBar) findViewById(R.id.circle_progress_bar1); mCircleProgressBar1.setProgress((int) (100 * Math.random()));随机生成一个 0.0 - 0.1 的数值乘以 100 设置为进度。 效果 可以看到动画效果 虽然 git 丢帧了 ~ 。 6.调整位置、宽高 前文我是设定了 View 宽高都是 300dp 并且绘制图形是随意指定的坐标。 实际开发时不可能用这些值所以要优化下绘制的逻辑。 实际使用时可能宽度高度一样宽度大于高度 宽度小于高度 采用这个逻辑 取宽度、高度的最小值作为圆的直径除以 2 得到半径。对角线交汇点作为圆心。 简言之以对角线为圆心画最大内切圆。 重写 onMeasure 方法重绘 View 的宽高这部分参考《Android 开发艺术探索》 private int DEFAULT_WIDTH 100;//默认宽度private int DEFAULT_HEIGHT 100;//默认宽度private int DEFAULT_RADIUS 50;//默认半径Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int widthMode MeasureSpec.getMode(widthMeasureSpec);int heightMode MeasureSpec.getMode(heightMeasureSpec);if (widthMode MeasureSpec.AT_MOST heightMode MeasureSpec.AT_MOST) {setMeasuredDimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);} else if (widthMode MeasureSpec.AT_MOST) {setMeasuredDimension(DEFAULT_WIDTH, heightMeasureSpec);} else if (heightMode MeasureSpec.AT_MOST) {setMeasuredDimension(widthMeasureSpec, DEFAULT_HEIGHT);}}修改 onDraw 绘制逻辑 Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// 圆心坐标是(centerX,centerY)int centerX getWidth()/2;int centerY getHeight()/2;//确定半径float radius Math.min(centerX, centerY) - paintCircleBottom.getStrokeWidth();//绘制底层圆形canvas.drawCircle(centerX, centerY, radius, paintCircleBottom);//绘制上层弧形,从顶部开始顺时针走 _anglecanvas.drawArc(centerX - radius,centerY-radius,centerX radius,centerY radius,270, _angle,false, paintArcTop);//绘制文本,文字中心和圆心保持一致Paint.FontMetrics fontMetrics paintText.getFontMetrics();float distance (fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom;float baseline centerY distance;canvas.drawText(dt.format(100 * _angle/360)%, centerX, baseline, paintText);//文字中心和圆心一致}分别写了 3 个布局布局依次是 宽度等于高度 、宽度大宇高度、宽度小于高度效果 至此基本是一个还可以的版本了。 附代码 贴下当前代码 CircleProgressBar.java package com.test.luodemo.customerview;import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.animation.AccelerateInterpolator;import androidx.annotation.Nullable;import java.text.DecimalFormat;public class CircleProgressBar extends View {private Paint paintCircleBottom new Paint();private Paint paintArcTop new Paint();private Paint paintText new Paint();private int DEFAULT_WIDTH 100;//默认宽度private int DEFAULT_HEIGHT 100;//默认宽度private int DEFAULT_RADIUS 50;//默认半径private float _angle;//弧形的角度public CircleProgressBar(Context context) {super(context);init();}public CircleProgressBar(Context context, Nullable AttributeSet attrs) {super(context, attrs);init();}public CircleProgressBar(Context context, Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}private void init(){//初始化文本的画笔paintText.setFlags(Paint.ANTI_ALIAS_FLAG);paintText.setColor(Color.BLACK);paintText.setTextAlign(Paint.Align.CENTER);paintText.setTextSize(80f);//初始化底层圆形的画笔paintCircleBottom.setFlags(Paint.ANTI_ALIAS_FLAG);paintCircleBottom.setColor(Color.LTGRAY);paintCircleBottom.setStrokeWidth(10f);paintCircleBottom.setStrokeCap(Paint.Cap.ROUND);paintCircleBottom.setStyle(Paint.Style.STROKE);//初始化弧形的画笔paintArcTop.setFlags(Paint.ANTI_ALIAS_FLAG);paintArcTop.setColor(Color.MAGENTA);paintArcTop.setStrokeWidth(10f);paintArcTop.setStrokeCap(Paint.Cap.ROUND);paintArcTop.setStyle(Paint.Style.STROKE);}Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int widthMode MeasureSpec.getMode(widthMeasureSpec);int heightMode MeasureSpec.getMode(heightMeasureSpec);if (widthMode MeasureSpec.AT_MOST heightMode MeasureSpec.AT_MOST) {setMeasuredDimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);} else if (widthMode MeasureSpec.AT_MOST) {setMeasuredDimension(DEFAULT_WIDTH, heightMeasureSpec);} else if (heightMode MeasureSpec.AT_MOST) {setMeasuredDimension(widthMeasureSpec, DEFAULT_HEIGHT);}}Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// 圆心坐标是(centerX,centerY)int centerX getWidth()/2;int centerY getHeight()/2;//确定半径float radius Math.min(centerX, centerY) - paintCircleBottom.getStrokeWidth();//绘制底层圆形canvas.drawCircle(centerX, centerY, radius, paintCircleBottom);//绘制上层弧形,从顶部开始顺时针走90°canvas.drawArc(centerX - radius,centerY-radius,centerX radius,centerY radius,270, _angle,false, paintArcTop);//绘制文本,文字中心和圆心保持一致DecimalFormat dt new DecimalFormat(0.##);Paint.FontMetrics fontMetrics paintText.getFontMetrics();float distance (fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom;float baseline centerY distance;canvas.drawText(dt.format(100 * _angle/360)%, centerX, baseline, paintText);//文字中心和圆心一致}/*** 设置进度展现动画* */public void setProgress(int progress){ValueAnimator animator ValueAnimator.ofFloat(0,100f);animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {Overridepublic void onAnimationUpdate(ValueAnimator animation) {float cur (float) animation.getAnimatedValue();_angle cur/100 * 360 * progress/100;invalidate();}});animator.setDuration(3000);animator.setInterpolator(new AccelerateInterpolator());animator.start();} }布局文件 ?xml version1.0 encodingutf-8? LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:apphttp://schemas.android.com/apk/res-autoxmlns:toolshttp://schemas.android.com/toolsandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentandroid:orientationverticaltools:context.customerview.CircleProgressBarActivityLinearLayoutandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:orientationhorizontalLinearLayoutandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgroundcolor/purple_200com.test.luodemo.customerview.CircleProgressBarandroid:idid/circle_progress_bar1android:layout_width300dpandroid:layout_height300dp //LinearLayoutLinearLayoutandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgroundcolor/teal_200com.test.luodemo.customerview.CircleProgressBarandroid:idid/circle_progress_bar2android:layout_width300dpandroid:layout_height200dp //LinearLayoutLinearLayoutandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgroundcolor/teal_700com.test.luodemo.customerview.CircleProgressBarandroid:idid/circle_progress_bar3android:layout_width200dpandroid:layout_height300dp //LinearLayout!--LinearLayoutandroid:layout_width50dpandroid:layout_height70dpandroid:backgroundcolor/purple_200com.test.luodemo.customerview.CircleProgressBarandroid:layout_widthmatch_parentandroid:layout_heightmatch_parent//LinearLayoutLinearLayoutandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgroundcolor/purple_200com.test.luodemo.customerview.CircleProgressBarandroid:layout_widthwrap_contentandroid:layout_heightwrap_content//LinearLayout--/LinearLayoutLinearLayoutandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:visibilityvisibleButtonandroid:idid/button_cpb1android:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:onClickonCPBButtonClickandroid:textButton1 /Buttonandroid:idid/button_cpb2android:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:onClickonCPBButtonClickandroid:textButton2 /Buttonandroid:idid/button_cpb3android:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:onClickonCPBButtonClickandroid:textButton3 /Buttonandroid:idid/button_cpb_allandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:onClickonCPBButtonClickandroid:textButton All //LinearLayout/LinearLayoutActivity 调用 public class CircleProgressBarActivity extends AppCompatActivity {private CircleProgressBar mCircleProgressBar1 , mCircleProgressBar2 , mCircleProgressBar3;Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_circle_progress_bar);Objects.requireNonNull(getSupportActionBar()).setTitle(CircleProgressBarActivity);mCircleProgressBar1 (CircleProgressBar) findViewById(R.id.circle_progress_bar1);mCircleProgressBar2 (CircleProgressBar) findViewById(R.id.circle_progress_bar2);mCircleProgressBar3 (CircleProgressBar) findViewById(R.id.circle_progress_bar3);}public void onCPBButtonClick(View view) {switch (view.getId()) {case R.id.button_cpb1:mCircleProgressBar1.setProgress((int) (100 * Math.random()));break;case R.id.button_cpb2:mCircleProgressBar2.setProgress((int) (100 * Math.random()));break;case R.id.button_cpb3:mCircleProgressBar3.setProgress((int) (100 * Math.random()));break;case R.id.button_cpb_all:mCircleProgressBar1.setProgress((int) (100 * Math.random()));mCircleProgressBar2.setProgress((int) (100 * Math.random()));mCircleProgressBar3.setProgress((int) (100 * Math.random()));break;default:break;}} }7.自定义属性 attr 需求是不停的会有这些需求可指定画笔宽度、颜色等、可指定动画时长等。 这些可以通过在自定义的View中创建 Java 接口来设置但我要学自定义View就要用 attr 。 7.1 创建 res/values/attrs.xml 如果已有就不用创建直接用就行了。 写入如下内容 ?xml version1.0 encodingutf-8? resources!-- 圆形进度条 --declare-styleable nameCircleProgressBarattr namecircleWidth formatfloat / !--底层圆形宽度--attr namecircleColor formatcolor / !--底层圆形颜色--attr namearcWidth formatfloat / !--上层弧形宽度--attr namearcColor formatcolor /!--上层弧形颜色--attr nametextColor formatcolor /!--文本颜色--attr nametextSize formatfloat /!--文本字体大小--attr nameinitProgress formatinteger /!--进度--/declare-styleable /resourcesdeclare-styleable nameCircleProgressBar 中 CircleProgressBar 就是自定义 View 的名字要保持一致。 不一致AS会报黄 By convention, the custom view (CircleProgressBar) and the declare-styleable (CircleProgressBar111) should have the same name (various editor features rely on this convention)attr namecircleWidth formatfloat / 是 CircleProgressBar 的属性可指定类型 类型说明boolean布尔类型true 或 falsecolor颜色值如 android:color/whitedimensiondp 值如 20dpenum枚举flags位或运算如 app:cus_view_gravity“top|right”fraction百分比如 30%floatfloat 型integerint 型reference引用资源如 drawable/picstring字符串 7.2 使用 TypedArray 获取 attrs 在构造函数中通过 TypedArray 获取自定义的属性。基本逻辑就是有设置 attr 就用设置的值没有就用默认值。 使用后一定要调用 TypedArray.recycle(); public CircleProgressBar(Context context, Nullable AttributeSet attrs) {super(context, attrs);TypedArray typedArray context.obtainStyledAttributes(attrs, R.styleable.CircleProgressBar);textColor typedArray.getColor(R.styleable.CircleProgressBar_textColor, Color.BLACK);textSize typedArray.getFloat(R.styleable.CircleProgressBar_textSize, 80f);circleColor typedArray.getColor(R.styleable.CircleProgressBar_circleColor, Color.LTGRAY);circleWidth typedArray.getFloat(R.styleable.CircleProgressBar_circleWidth, 10f);arcColor typedArray.getColor(R.styleable.CircleProgressBar_arcColor, Color.MAGENTA);arcWidth typedArray.getFloat(R.styleable.CircleProgressBar_arcWidth, 10f);progress typedArray.getInt(R.styleable.CircleProgressBar_initProgress, 0);typedArray.recycle();init();}有两个带 AttributeSet 参数的构造函数 public CircleProgressBar(Context context, Nullable AttributeSet attrs) {}public CircleProgressBar(Context context, Nullable AttributeSet attrs, int defStyleAttr) {} 为什么用后面这个 因为我们是在 xml 中定义的 CircleProgressBar 。参考源码说明 /*** Constructor that is called when inflating a view from XML. This is called* when a view is being constructed from an XML file, supplying attributes* that were specified in the XML file. This version uses a default style of* 0, so the only attribute values applied are those in the Contexts Theme* and the given AttributeSet.** p* The method onFinishInflate() will be called after all children have been* added.** param context The Context the view is running in, through which it can* access the current theme, resources, etc.* param attrs The attributes of the XML tag that is inflating the view.* see #View(Context, AttributeSet, int)*/public View(Context context, Nullable AttributeSet attrs) {this(context, attrs, 0);}/*** Perform inflation from XML and apply a class-specific base style from a* theme attribute. This constructor of View allows subclasses to use their* own base style when they are inflating. For example, a Button classs* constructor would call this version of the super class constructor and* supply codeR.attr.buttonStyle/code for vardefStyleAttr/var; this* allows the themes button style to modify all of the base view attributes* (in particular its background) as well as the Button classs attributes.** param context The Context the view is running in, through which it can* access the current theme, resources, etc.* param attrs The attributes of the XML tag that is inflating the view.* param defStyleAttr An attribute in the current theme that contains a* reference to a style resource that supplies default values for* the view. Can be 0 to not look for defaults.* see #View(Context, AttributeSet)*/public View(Context context, Nullable AttributeSet attrs, int defStyleAttr) {this(context, attrs, defStyleAttr, 0);}7.3 在 xml 中初始化 attr xml 关键代码如下 LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:apphttp://schemas.android.com/apk/res-auto !-- 注释1-- xmlns:toolshttp://schemas.android.com/toolsandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentandroid:orientationverticaltools:context.customerview.CircleProgressBarActivity!-- ... -- LinearLayoutandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgroundcolor/purple_200com.test.luodemo.customerview.CircleProgressBarandroid:idid/circle_progress_bar1android:layout_width300dpandroid:layout_height300dp!-- 注释2-- app:circleColorandroid:color/whiteapp:circleWidth30app:arcColorcolor/my_redapp:arcWidth15app:textColorandroid:color/holo_orange_darkapp:initProgress30!-- 注释2--//LinearLayout!-- ... -- /LinearLayout注释2处就是初始化 attr 以为 app 开头是对应注释1处。 7.4 效果 左一是自定义 attr 的效果左二、左三是没有自定义 attr 的效果。 差异有底层圆形的颜色、画笔大小上层弧形的颜色、画笔大小、开始的角度中间文字的颜色。 说明自定义 attr 起效了。 附代码V2 CircleProgressBar.java package com.test.luodemo.customerview;import android.animation.ValueAnimator; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.animation.AccelerateInterpolator;import androidx.annotation.Nullable;import com.test.luodemo.R;import java.text.DecimalFormat;public class CircleProgressBar extends View {private Paint paintCircleBottom new Paint();private Paint paintArcTop new Paint();private Paint paintText new Paint();private int DEFAULT_WIDTH 100;//默认宽度private int DEFAULT_HEIGHT 100;//默认宽度private int DEFAULT_RADIUS 50;//默认半径private float _angle;//弧形的角度/***************************** attr *******************************/int textColor;float textSize;int circleColor ;int arcColor;float circleWidth;float arcWidth;int progress;/***************************** attr *******************************/public CircleProgressBar(Context context) {super(context);init();}public CircleProgressBar(Context context, Nullable AttributeSet attrs) {super(context, attrs);TypedArray typedArray context.obtainStyledAttributes(attrs, R.styleable.CircleProgressBar);textColor typedArray.getColor(R.styleable.CircleProgressBar_textColor, Color.BLACK);textSize typedArray.getFloat(R.styleable.CircleProgressBar_textSize, 80f);circleColor typedArray.getColor(R.styleable.CircleProgressBar_circleColor, Color.LTGRAY);circleWidth typedArray.getFloat(R.styleable.CircleProgressBar_circleWidth, 10f);arcColor typedArray.getColor(R.styleable.CircleProgressBar_arcColor, Color.MAGENTA);arcWidth typedArray.getFloat(R.styleable.CircleProgressBar_arcWidth, 10f);progress typedArray.getInt(R.styleable.CircleProgressBar_initProgress, 0);typedArray.recycle();init();}public CircleProgressBar(Context context, Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}private void init(){//初始化文本的画笔paintText.setFlags(Paint.ANTI_ALIAS_FLAG);paintText.setStyle(Paint.Style.FILL);paintText.setColor(textColor);//设置自定义属性值paintText.setTextAlign(Paint.Align.CENTER);paintText.setTextSize(textSize);//初始化底层圆形的画笔paintCircleBottom.setFlags(Paint.ANTI_ALIAS_FLAG);paintCircleBottom.setStrokeCap(Paint.Cap.ROUND);paintCircleBottom.setStyle(Paint.Style.STROKE);paintCircleBottom.setColor(circleColor);//设置自定义属性值paintCircleBottom.setStrokeWidth(circleWidth);//设置自定义属性值//初始化弧形的画笔paintArcTop.setFlags(Paint.ANTI_ALIAS_FLAG);paintArcTop.setStrokeCap(Paint.Cap.ROUND);paintArcTop.setStyle(Paint.Style.STROKE);paintArcTop.setColor(arcColor);//设置自定义属性值paintArcTop.setStrokeWidth(arcWidth);//设置自定义属性值_angle progress;}Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int widthMode MeasureSpec.getMode(widthMeasureSpec);int heightMode MeasureSpec.getMode(heightMeasureSpec);if (widthMode MeasureSpec.AT_MOST heightMode MeasureSpec.AT_MOST) {setMeasuredDimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);} else if (widthMode MeasureSpec.AT_MOST) {setMeasuredDimension(DEFAULT_WIDTH, heightMeasureSpec);} else if (heightMode MeasureSpec.AT_MOST) {setMeasuredDimension(widthMeasureSpec, DEFAULT_HEIGHT);}}Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// 圆心坐标是(centerX,centerY)int centerX getWidth()/2;int centerY getHeight()/2;//确定半径float radius Math.min(centerX, centerY) - paintCircleBottom.getStrokeWidth();//绘制底层圆形canvas.drawCircle(centerX, centerY, radius, paintCircleBottom);//绘制上层弧形,从顶部开始顺时针走90°canvas.drawArc(centerX - radius,centerY-radius,centerX radius,centerY radius,270, _angle,false, paintArcTop);//绘制文本,文字中心和圆心保持一致DecimalFormat dt new DecimalFormat(0.##);Paint.FontMetrics fontMetrics paintText.getFontMetrics();float distance (fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom;float baseline centerY distance;canvas.drawText(dt.format(100 * _angle/360)%, centerX, baseline, paintText);//文字中心和圆心一致}/*** 设置进度展现动画* */public void setProgress(int progress){ValueAnimator animator ValueAnimator.ofFloat(0,100f);animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {Overridepublic void onAnimationUpdate(ValueAnimator animation) {float cur (float) animation.getAnimatedValue();_angle cur/100 * 360 * progress/100;invalidate();}});animator.setDuration(3000);animator.setInterpolator(new AccelerateInterpolator());animator.start();} }布局文件 ?xml version1.0 encodingutf-8? LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:apphttp://schemas.android.com/apk/res-autoxmlns:toolshttp://schemas.android.com/toolsandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentandroid:orientationverticaltools:context.customerview.CircleProgressBarActivityLinearLayoutandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:orientationhorizontalLinearLayoutandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgroundcolor/purple_200com.test.luodemo.customerview.CircleProgressBarandroid:idid/circle_progress_bar1android:layout_width300dpandroid:layout_height300dpapp:circleColorandroid:color/whiteapp:circleWidth30app:arcColorcolor/my_redapp:arcWidth15app:textColorandroid:color/holo_orange_darkapp:initProgress30//LinearLayoutLinearLayoutandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgroundcolor/teal_200com.test.luodemo.customerview.CircleProgressBarandroid:idid/circle_progress_bar2android:layout_width300dpandroid:layout_height200dp //LinearLayoutLinearLayoutandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgroundcolor/teal_700com.test.luodemo.customerview.CircleProgressBarandroid:idid/circle_progress_bar3android:layout_width200dpandroid:layout_height300dp //LinearLayout/LinearLayoutLinearLayoutandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:visibilityvisibleButtonandroid:idid/button_cpb1android:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:onClickonCPBButtonClickandroid:textButton1 /Buttonandroid:idid/button_cpb2android:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:onClickonCPBButtonClickandroid:textButton2 /Buttonandroid:idid/button_cpb3android:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:onClickonCPBButtonClickandroid:textButton3 /Buttonandroid:idid/button_cpb_allandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:onClickonCPBButtonClickandroid:textButton All //LinearLayout/LinearLayoutActivity 调用 和之前一样。 attrs ?xml version1.0 encodingutf-8? resources!-- 圆形进度条 --declare-styleable nameCircleProgressBarattr namecircleWidth formatfloat / !--底层圆形宽度--attr namecircleColor formatcolor / !--底层圆形颜色--attr namearcWidth formatfloat / !--上层弧形宽度--attr namearcColor formatcolor /!--上层弧形颜色--attr nametextColor formatcolor /!--文本颜色--attr nametextSize formatfloat /!--文本字体大小--attr nameinitProgress formatinteger /!--进度--/declare-styleable /resources参考资料 Android属性动画深入分析让你成为动画牛人_singwhatiwanna的博客-CSDN博客 Android Canvas的使用_南国樗里疾的博客-CSDN博客 Android Canvas的drawText()和文字居中方案 - 简书
http://www.dnsts.com.cn/news/79782.html

相关文章:

  • 仙游住房与城乡建设局网站青岛php网站建设
  • 网站悬浮代码wordpress 网站实例
  • 别人做的网站自己想更新html首页制作
  • 阿里网站建设需要准备什么软件互联网平台
  • 西蔵自治区建设厅网站制作自己的网站需要什么材料
  • 做有声小说网站滕州建设局网站
  • 免费自己怎么注册网站天津市最新消息今天
  • 那些做电影的网站赚钱吗做淘口令网站
  • 建筑类企业网站模板网站建设合同注意点
  • 培训学校地址网站建设哪家购物网站做的好
  • 网站建设方案如何讲解网站设计与制作的基本步骤
  • 做毕业设计个人网站任务书网络营销文案策划
  • 网站备案的幕布尺寸市场营销推广方案怎么做
  • 制作app的网站wordpress多个标签
  • 凡科网站做网站多少钱深圳宣传片制作设计
  • 网站广告代理如何做如今做那些网站致富
  • 张家港企业网站设计wordpress中文企业主题
  • 徐闻网站建设公司wordpress缩略图代码
  • 昆明网站建设流程毕业设计php做网站
  • wordpress美容养生seo的描述正确
  • 做58网站空调维修接单怎么样全国集团网站建设
  • 网站开发好公司查找使用wordpress的网站
  • 学校学不到网站建设个人网站怎么做代码
  • 百度云建网站最佳品牌营销策划公司
  • 影响网站排名的因素网络平台管理制度
  • 创意设计公司网站重庆网站建设mlfart
  • 网站模板 单页免费咨询妇科医生在线
  • 电商网站购买的流程图网创是什么
  • 长春教做网站带维护的培训机构没内涵网站源码
  • 建站之星和凡科网站建设方案范文8篇