热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android自定义View圆形百分比控件(一)

这篇文章主要为大家详细介绍了Android自定义View圆形百分比控件的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

做一个自定义View的小练习,效果如下

这里写图片描述

只需要画一个圆、一个圆弧、一个百分比文本,添加一个点击事件,传入百分比重绘

1、在res/values文件夹下新建attrs.xml文件,编写自定义属性:

<&#63;xml version="1.0" encoding="utf-8"&#63;>

  
    
    
    
    
    
    
  

2、新建CirclePercentView继承View,重写构造方法:

public CirclePercentView(Context context) {
    this(context, null);
  }

  public CirclePercentView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public CirclePercentView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
  }

3、在第三个构造方法中获取自定义属性的值:

    TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CirclePercentView, defStyleAttr, 0);
    mCircleColor = ta.getColor(R.styleable.CirclePercentView_circleBg, 0xff8e29fa);
    mArcColor = ta.getColor(R.styleable.CirclePercentView_arcColor, 0xffffee00);
    mArcWidth = ta.getDimensionPixelSize(R.styleable.CirclePercentView_arcWidth, DensityUtils.dp2px(context, 16));
    mPercentTextColor = ta.getColor(R.styleable.CirclePercentView_arcColor, 0xffffee00);
    mPercentTextSize = ta.getDimensionPixelSize(R.styleable.CirclePercentView_percentTextSize, DensityUtils.sp2px(context, 16));
    mRadius = ta.getDimensionPixelSize(R.styleable.CirclePercentView_radius, DensityUtils.dp2px(context, 100));
    ta.recycle();

4、创建画图所使用的对象,如Paint、Rect、RectF:

    mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mCirclePaint.setStyle(Paint.Style.FILL);
    mCirclePaint.setColor(mCircleColor);

    mArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mArcPaint.setStyle(Paint.Style.STROKE);
    mArcPaint.setStrokeWidth(mArcWidth);
    mArcPaint.setColor(mArcColor);
    mArcPaint.setStrokeCap(Paint.Cap.ROUND);//使圆弧两头圆滑

    mPercentTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mPercentTextPaint.setStyle(Paint.Style.STROKE);
    mPercentTextPaint.setColor(mPercentTextColor);
    mPercentTextPaint.setTextSize(mPercentTextSize);

    mArcRectF = new RectF();//圆弧的外接矩形

    mTextBound = new Rect();//文本的范围矩形

5、重写onMeasure()方法,计算自定义View的宽高:

 @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension(measureDimension(widthMeasureSpec), measureDimension(heightMeasureSpec));
  }

  private int measureDimension(int measureSpec) {
    int result;
    int specMode = MeasureSpec.getMode(measureSpec);
    int specSize = MeasureSpec.getSize(measureSpec);
    if (specMode == MeasureSpec.EXACTLY) {//精确地,代表宽高为定值或者match_parent时
      result = specSize;
    } else {
      result = 2 * mRadius;
      if (specMode == MeasureSpec.AT_MOST) {//最大地,代表宽高为wrap_content时
        result = Math.min(result, specSize);
      }
    }
    return result;
  }

6、重写onDraw()方法,绘制圆、圆弧和百分比文本,注意坐标的计算:

这里写图片描述

  @Override
  protected void onDraw(Canvas canvas) {
    //画圆
    canvas.drawCircle(getWidth() / 2, getHeight() / 2, mRadius, mCirclePaint);

    //画圆弧
    mArcRectF.set(getWidth() / 2 - mRadius + mArcWidth / 2, getHeight() / 2 - mRadius + mArcWidth / 2
        , getWidth() / 2 + mRadius - mArcWidth / 2, getHeight() / 2 + mRadius - mArcWidth / 2);
    canvas.drawArc(mArcRectF, 270, 360 * mCurPercent / 100, false, mArcPaint);

    String text = mCurPercent + "%";
    //计算文本宽高
    mPercentTextPaint.getTextBounds(text, 0, String.valueOf(text).length(), mTextBound);
    //画百分比文本
    canvas.drawText(text, getWidth() / 2 - mTextBound.width() / 2
        , getHeight() / 2 + mTextBound.height() / 2, mPercentTextPaint);
  }

7、给这个view设置点击事件,暴露一个动态设置百分比的方法:

  public void setCurPercent(float curPercent) {
    ValueAnimator anim = ValueAnimator.ofFloat(mCurPercent, curPercent);
    //动画时长由百分比大小决定
    anim.setDuration((long) (Math.abs(mCurPercent - curPercent) * 20));
    anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
      @Override
      public void onAnimationUpdate(ValueAnimator animation) {
        float value = (float) animation.getAnimatedValue();
        mCurPercent = (float) (Math.round(value * 10)) / 10;//四舍五入保留到小数点后两位
        invalidate();//重绘,重走onDraw()方法,这也是不能再onDraw()中创建对象的原因
      }
    });
    anim.start();
  }

  public void setOnCircleClickListener(OnClickListener onClickListener) {
    this.mOnClickListener= onClickListener;
  }

    //在构造方法中
    setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        if (mOnClickListener != null) {
          mOnClickListener.onClick(CirclePercentView.this);
        }
      }
    });

8、在activity_main.xml布局文件中使用该View:




  
  


9、在MainActivity.java中设置监听,传入百分比:

  mCirclePercentView = (CirclePercentView) findViewById(R.id.circlePercentView);
  mCirclePercentView.setOnCircleClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
      float percent = (float) (Math.random() * 99 + 1);
      mCirclePercentView.setCurPercent(percent);
    }
  });


代码下载地址:
https://github.com/MonkeyMushroom/CirclePercentView/tree/master

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • Google Play推出全新的应用内评价API,帮助开发者获取更多优质用户反馈。用户每天在Google Play上发表数百万条评论,这有助于开发者了解用户喜好和改进需求。开发者可以选择在适当的时间请求用户撰写评论,以获得全面而有用的反馈。全新应用内评价功能让用户无需返回应用详情页面即可发表评论,提升用户体验。 ... [详细]
  • 打开文件管理器_【教程】模组管理器3.1食用指南
    文编:byakko最近有部分小伙伴反应还不会使用unity模组管理器,现在我就给大家讲一下unity模组管理器——从下载到使用。完整视频版以下是无WiF ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 学习笔记(34):第三阶段4.2.6:SpringCloud Config配置中心的应用与原理第三阶段4.2.6SpringCloud Config配置中心的应用与原理
    立即学习:https:edu.csdn.netcourseplay29983432482?utm_sourceblogtoedu配置中心得核心逻辑springcloudconfi ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 20211101CleverTap参与度和分析工具功能平台学习/实践
    1.应用场景主要用于学习CleverTap的使用,该平台主要用于客户保留与参与平台.为客户提供价值.这里接触到的原因,是目前公司用到该平台的服务~2.学习操作 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
author-avatar
无心之无心
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有