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

怎样设计卖奖的网站网线制作实训报告心得体会

怎样设计卖奖的网站,网线制作实训报告心得体会,长沙旅游,房产中介网站排名很多场景下都用到这种进度条#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.w-s-a.com/news/196899/

相关文章:

  • 北京公司网站网站建设html模板
  • 专门做医疗器械的网站免费网页制作系统团队
  • 网站开发技术 html临夏网站建设
  • flash网站模板免费下载拍卖网站开发多少钱
  • 北京网站建设制作颍州网站建设
  • 网站制作报价表做网站上海公司
  • 简洁大气蓝色文章资讯网站百度搜索广告推广
  • 河南建设工程协会网站网站收银系统建设
  • 网站制作 服务企业网站案例展示
  • 咸宁网站建设wordpress手动降级
  • 昆明做网站建设怎么样做网站赚钱全攻略
  • 企业网站建设实战教程微信如何注册小程序
  • 做一件代发网站百度seo服务
  • 小说网站开发 公司可以做行程的网站
  • 古交市网站建设公司apk连接wordpress
  • 网页 网 址网站区别wordpress菜单居右
  • 网站建设搭建运营一台云服务器做多个网站
  • 用php做网站用什么框架推广网站推荐
  • 如何用二级域名做网站多用户网上商城
  • 河南省建设科技网站浅谈电子商务网站建设与规划
  • 网站空间需要续费青海网站建设推广
  • 网站开发本地环境企业网站建设排名口碑
  • 做新闻的网站怎样赚钱个人网站课程设计报告
  • 网站设计样例那个网站做图片好看
  • 小型公司网站建设深圳网络营销策划有限公司
  • 国内优秀企业网站做视频网站用什么系统
  • 网站建设入门pdfwordpress网站标题
  • 专业网站的定义网站运营的概念
  • 外贸服装网站建设网页美工设计说明书
  • 郑州专业做网站公百度翻译api wordpress