96SEO 2026-02-19 17:01 7
绘制底层圆形#xff1b;在同位置绘制上层弧形#xff0c;但颜色不同#xff…很多场景下都用到这种进度条有的还带动画效果

绘制底层圆形在同位置绘制上层弧形但颜色不同在中心点绘制文本显示进度。
com.test.luodemo.customerview;import
androidx.annotation.Nullable;public
LinearLayoutandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:backgroundcolor/purple_200com.test.luodemo.customerview.CircleProgressBarandroid:layout_width300dpandroid:layout_height300dp//LinearLayout此时运行是没效果的因为这个View还没有绘制啥也没有。
com.test.luodemo.customerview;import
androidx.annotation.Nullable;public
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
{super.onDraw(canvas);//绘制底层圆形canvas.drawCircle(300,
{super.onDraw(canvas);//绘制底层圆形canvas.drawCircle(
paintCircleBottom);//绘制上层弧形,从顶部开始顺时针走90°_angle
90;canvas.drawArc(100,100,500,500,270,
格式化输入保留小数点后两位如果小数点后两位都是0则不显示小数点后两位。
{super.onDraw(canvas);//绘制底层圆形canvas.drawCircle(300,
paintCircleBottom);//绘制上层弧形,从顶部开始顺时针走90°_angle
90;canvas.drawArc(100,100,500,500,270,
paintArcTop);//绘制文本DecimalFormat
DecimalFormat(0.##);canvas.drawText(dt.format(100
//绘制文本,文字中心和圆心保持一致Paint.FontMetrics
paintText.getFontMetrics();float
distance;canvas.drawText(dt.format(100
{super.onDraw(canvas);//绘制底层圆形canvas.drawCircle(300,
paintCircleBottom);//绘制上层弧形,从顶部开始顺时针走90°canvas.drawArc(100,100,500,500,270,
paintArcTop);//绘制文本,文字中心和圆心保持一致DecimalFormat
DecimalFormat(0.##);Paint.FontMetrics
paintText.getFontMetrics();float
distance;canvas.drawText(dt.format(100
ValueAnimator.ofFloat(0,100f);animator.addUpdateListener(new
ValueAnimator.AnimatorUpdateListener()
onAnimationUpdate(ValueAnimator
animation.getAnimatedValue();_angle
View}});animator.setDuration(3000);animator.setInterpolator(new
AccelerateInterpolator());animator.start();}注意要去掉
findViewById(R.id.circle_progress_bar1);
mCircleProgressBar1.setProgress((int)
{super.onMeasure(widthMeasureSpec,
MeasureSpec.getMode(widthMeasureSpec);int
MeasureSpec.getMode(heightMeasureSpec);if
{setMeasuredDimension(DEFAULT_WIDTH,
{setMeasuredDimension(DEFAULT_WIDTH,
{setMeasuredDimension(widthMeasureSpec,
paintCircleBottom.getStrokeWidth();//绘制底层圆形canvas.drawCircle(centerX,
paintCircleBottom);//绘制上层弧形,从顶部开始顺时针走
paintArcTop);//绘制文本,文字中心和圆心保持一致Paint.FontMetrics
paintText.getFontMetrics();float
distance;canvas.drawText(dt.format(100
com.test.luodemo.customerview;import
android.animation.ValueAnimator;
android.view.animation.AccelerateInterpolator;import
androidx.annotation.Nullable;import
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
{super.onMeasure(widthMeasureSpec,
MeasureSpec.getMode(widthMeasureSpec);int
MeasureSpec.getMode(heightMeasureSpec);if
{setMeasuredDimension(DEFAULT_WIDTH,
{setMeasuredDimension(DEFAULT_WIDTH,
{setMeasuredDimension(widthMeasureSpec,
DEFAULT_HEIGHT);}}Overrideprotected
paintCircleBottom.getStrokeWidth();//绘制底层圆形canvas.drawCircle(centerX,
paintCircleBottom);//绘制上层弧形,从顶部开始顺时针走90°canvas.drawArc(centerX
paintArcTop);//绘制文本,文字中心和圆心保持一致DecimalFormat
DecimalFormat(0.##);Paint.FontMetrics
paintText.getFontMetrics();float
distance;canvas.drawText(dt.format(100
ValueAnimator.ofFloat(0,100f);animator.addUpdateListener(new
ValueAnimator.AnimatorUpdateListener()
onAnimationUpdate(ValueAnimator
animation.getAnimatedValue();_angle
progress/100;invalidate();}});animator.setDuration(3000);animator.setInterpolator(new
AccelerateInterpolator());animator.start();}
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
//LinearLayout/LinearLayoutActivity
mCircleProgressBar3;Overrideprotected
{super.onCreate(savedInstanceState);setContentView(R.layout.activity_circle_progress_bar);Objects.requireNonNull(getSupportActionBar()).setTitle(CircleProgressBarActivity);mCircleProgressBar1
findViewById(R.id.circle_progress_bar1);mCircleProgressBar2
findViewById(R.id.circle_progress_bar2);mCircleProgressBar3
findViewById(R.id.circle_progress_bar3);}public
R.id.button_cpb1:mCircleProgressBar1.setProgress((int)
R.id.button_cpb2:mCircleProgressBar2.setProgress((int)
R.id.button_cpb3:mCircleProgressBar3.setProgress((int)
R.id.button_cpb_all:mCircleProgressBar1.setProgress((int)
Math.random()));mCircleProgressBar2.setProgress((int)
Math.random()));mCircleProgressBar3.setProgress((int)
Math.random()));break;default:break;}}
需求是不停的会有这些需求可指定画笔宽度、颜色等、可指定动画时长等。
app:cus_view_gravity“top|right”fraction百分比如
context.obtainStyledAttributes(attrs,
R.styleable.CircleProgressBar);textColor
typedArray.getColor(R.styleable.CircleProgressBar_textColor,
typedArray.getFloat(R.styleable.CircleProgressBar_textSize,
typedArray.getColor(R.styleable.CircleProgressBar_circleColor,
typedArray.getFloat(R.styleable.CircleProgressBar_circleWidth,
typedArray.getColor(R.styleable.CircleProgressBar_arcColor,
typedArray.getFloat(R.styleable.CircleProgressBar_arcWidth,
typedArray.getInt(R.styleable.CircleProgressBar_initProgress,
0);typedArray.recycle();init();}有两个带
xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:apphttp://schemas.android.com/apk/res-auto
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!--
app:circleColorandroid:color/whiteapp:circleWidth30app:arcColorcolor/my_redapp:arcWidth15app:textColorandroid:color/holo_orange_darkapp:initProgress30!--
差异有底层圆形的颜色、画笔大小上层弧形的颜色、画笔大小、开始的角度中间文字的颜色。
com.test.luodemo.customerview;import
android.animation.ValueAnimator;
android.content.res.TypedArray;
android.view.animation.AccelerateInterpolator;import
androidx.annotation.Nullable;import
_angle;//弧形的角度/*****************************
*******************************/int
progress;/*****************************
*******************************/public
context.obtainStyledAttributes(attrs,
R.styleable.CircleProgressBar);textColor
typedArray.getColor(R.styleable.CircleProgressBar_textColor,
typedArray.getFloat(R.styleable.CircleProgressBar_textSize,
typedArray.getColor(R.styleable.CircleProgressBar_circleColor,
typedArray.getFloat(R.styleable.CircleProgressBar_circleWidth,
typedArray.getColor(R.styleable.CircleProgressBar_arcColor,
typedArray.getFloat(R.styleable.CircleProgressBar_arcWidth,
typedArray.getInt(R.styleable.CircleProgressBar_initProgress,
0);typedArray.recycle();init();}public
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
{super.onMeasure(widthMeasureSpec,
MeasureSpec.getMode(widthMeasureSpec);int
MeasureSpec.getMode(heightMeasureSpec);if
{setMeasuredDimension(DEFAULT_WIDTH,
{setMeasuredDimension(DEFAULT_WIDTH,
{setMeasuredDimension(widthMeasureSpec,
DEFAULT_HEIGHT);}}Overrideprotected
paintCircleBottom.getStrokeWidth();//绘制底层圆形canvas.drawCircle(centerX,
paintCircleBottom);//绘制上层弧形,从顶部开始顺时针走90°canvas.drawArc(centerX
paintArcTop);//绘制文本,文字中心和圆心保持一致DecimalFormat
DecimalFormat(0.##);Paint.FontMetrics
paintText.getFontMetrics();float
distance;canvas.drawText(dt.format(100
ValueAnimator.ofFloat(0,100f);animator.addUpdateListener(new
ValueAnimator.AnimatorUpdateListener()
onAnimationUpdate(ValueAnimator
animation.getAnimatedValue();_angle
progress/100;invalidate();}});animator.setDuration(3000);animator.setInterpolator(new
AccelerateInterpolator());animator.start();}
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
//LinearLayout/LinearLayoutActivity
Android属性动画深入分析让你成为动画牛人_singwhatiwanna的博客-CSDN博客
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback