Android自定义View绘制彩色圆弧

本文实例为大家分享了Android自定义View绘制彩色圆弧的具体代码,供大家参考,具体内容如下

效果如下:

自定义View代码如下:

package com.example.yan;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by xiaoyanzi on 2016/3/18.
 * 渐变圆弧
 */
public class GradualView extends View {

 private Context context;
 private Paint paint;//画笔
 private Paint paintFull;//实心圆画笔
 private Paint textPaint;//标识字画笔
 private Paint valuePaint;//移动小球画笔
 private int[] mColors;//渐变色数组

 private int centerX;//中心X
 private int centerY;//中心Y
 private int srcH;//控件高度
 private float startAngle = 110;//圆弧起始角度
 private float sweepAngle = 320;//圆弧所占度数
 private float airValue = 66;

 /**
 * 直接在代码中调用时,使用该函数
 *
 * @param context
 */
 public GradualView(Context context) {
 super(context);
 initData(context);
 }

 /**
 * 在xml中使用自定义view时,使用这个函数
 *
 * @param context
 * @param attrs
 */
 public GradualView(Context context, AttributeSet attrs) {
 super(context, attrs);
 initData(context);
 }

 /**
 * 可以由上一个函数中手动调用
 *
 * @param context
 * @param atrrs
 * @param defStyle 自定义函数中的attrs表示view的属性集,defStyle表示默认的属性资源集的id
 */
 public GradualView(Context context, AttributeSet atrrs, int defStyle) {
 super(context, atrrs, defStyle);
 }

 /**
 * 初始化
 * @param context
 */
 private void initData(Context context) {
 this.context = context;
 paint = new Paint(Paint.ANTI_ALIAS_FLAG);
 paint.setStyle(Paint.Style.STROKE);
 mColors = new int[]{
  0xFF660099,//紫色
  0xFF330033,//褐色
  0xFF99FF00,//草绿色
  0xFFFFFF00,//黄色
  0xFFFF6600,//橘色
  0xFFFF0000,//红色
  0xFF660099,//紫色

 };
 Shader s = new SweepGradient(0, 0, mColors, null);
 paint.setAntiAlias(true);//设置画笔为无锯齿
 paint.setStrokeWidth(dip2px(context, 14));//线宽
 paint.setShader(s);
 paintFull = new Paint(Paint.ANTI_ALIAS_FLAG);
 paintFull.setStyle(Paint.Style.FILL_AND_STROKE);
 paintFull.setAntiAlias(true);//设置画笔为无锯齿
 paintFull.setShader(s);
 textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
 textPaint.setTextSize(dip2px(context, 22));//设置字体大小
 textPaint.setColor(0xFFFFFFFF);
 valuePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
 valuePaint.setAntiAlias(true);//设置画笔为无锯齿
 }

 public void setAirValue(float airValue) {
 this.airValue = airValue;
 }

 @Override
 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
 super.onSizeChanged(w, h, oldw, oldh);
 srcH = h;
 centerX = w / 2;
 centerY = h / 2;
 }

 @Override
 protected void onDraw(Canvas canvas) {
 super.onDraw(canvas);
 float r = srcH / 2 - paint.getStrokeWidth() * 0.5f - dip2px(context, 200);
 //移动中心
 canvas.translate(centerX, centerY);
 RectF oval = new RectF();
 oval.left = -r;//左边
 oval.top = -r;//上边
 oval.right = r;//右边
 oval.bottom = r;//下边
 canvas.drawArc(oval, startAngle, sweepAngle, false, paint); //绘制圆弧
 //绘制圆弧两头的小圆
 float mr = dip2px(context, 7);
 float x1 = (float) (-r * Math.sin((360 - sweepAngle) / 2 * Math.PI / 180));
 float y1 = (float) (r * Math.cos((360 - sweepAngle) / 2 * Math.PI / 180));
 canvas.drawCircle(x1, y1, mr, paintFull);
 float x2 = (float) (r * Math.sin((360 - sweepAngle) / 2 * Math.PI / 180));
 float y2 = (float) (r * Math.cos((360 - sweepAngle) / 2 * Math.PI / 180));
 canvas.drawCircle(x2, y2, mr, paintFull);
 //小圆离球的距离
 float range = r + dip2px(context, 30);
 float ar = 12f;
 //画周围小球和数字
 float ax1 = (float) (-range * Math.sin(45 * Math.PI / 180));
 float ay1 = (float) (range * Math.cos(45 * Math.PI / 180));
 canvas.drawCircle(ax1, ay1, ar, paintFull);
 canvas.drawText("0", ax1 - getTextW() * 3, ay1 + getTextH() / 2, textPaint);
 float ax2 = -range;
 float ay2 = 0;
 canvas.drawCircle(ax2, ay2, ar, paintFull);
 canvas.drawText("50", ax2 - getTextW() * 5, ay2 + getTextH() / 2, textPaint);
 float ax3 = (float) (-range * Math.sin(45 * Math.PI / 180));
 float ay3 = (float) (-range * Math.cos(45 * Math.PI / 180));
 canvas.drawCircle(ax3, ay3, ar, paintFull);
 canvas.drawText("100", ax3 - getTextW() * 7, ay3 + getTextH() / 2, textPaint);
 float ax4 = 0;
 float ay4 = -range;
 canvas.drawCircle(ax4, ay4, ar, paintFull);
 canvas.drawText("150", ax4 - getTextW() * 3, ay4 - getTextH(), textPaint);
 float ax5 = (float) (range * Math.sin(45 * Math.PI / 180));
 float ay5 = (float) (-range * Math.cos(45 * Math.PI / 180));
 canvas.drawCircle(ax5, ay5, ar, paintFull);
 canvas.drawText("200", ax5 + getTextW(), ay5 + getTextH() / 2, textPaint);
 float ax6 = range;
 float ay6 = 0;
 canvas.drawCircle(ax6, ay6, ar, paintFull);
 canvas.drawText("300", ax6 + getTextW(), ay6 + getTextH() / 2, textPaint);
 float ax7 = (float) (range * Math.sin(45 * Math.PI / 180));
 float ay7 = (float) (range * Math.cos(45 * Math.PI / 180));
 canvas.drawCircle(ax7, ay7, ar, paintFull);
 canvas.drawText("500", ax7 + getTextW(), ay7 + getTextH() / 2, textPaint);
 //画标识小球
 valuePaint.setColor(0xFFFFFFFF);
 float cx;
 float cy;
 if (airValue >= 0 && airValue <= 50) {
  cx = (float) (-r * Math.cos((45 - airValue * 0.9) * Math.PI / 180));
  cy = (float) (r * Math.sin((45 - airValue * 0.9) * Math.PI / 180));
 } else if (airValue > 50 && airValue <= 150) {
  cx = (float) (-r * Math.cos((airValue * 0.9 - 45) * Math.PI / 180));
  cy = (float) (-r * Math.sin((airValue * 0.9 - 45) * Math.PI / 180));
 } else if (airValue > 150 && airValue <= 200) {
  cx = (float) (-r * Math.cos((airValue * 0.9 - 45) * Math.PI / 180));
  cy = (float) (-r * Math.sin((airValue * 0.9 - 45) * Math.PI / 180));
 } else if (airValue > 200 && airValue <= 300) {
  cx = (float) (-r * Math.cos((airValue * 0.45 + 45) * Math.PI / 180));
  cy = (float) (-r * Math.sin((airValue * 0.45 + 45) * Math.PI / 180));
 } else if (airValue > 300 && airValue <= 500) {//此处有问题
  cx = (float) (r * Math.cos(((airValue - 300) * 0.225) * Math.PI / 180));
  cy = (float) (r * Math.sin(((airValue - 300) * 0.225) * Math.PI / 180));
 } else {
  cx = (float) (-r * Math.cos(45 * Math.PI / 180));
  cy = (float) (r * Math.sin(45 * Math.PI / 180));
 }
 canvas.drawCircle(cx, cy, dip2px(context, 11), valuePaint);
 canvas.drawCircle(cx, cy, dip2px(context, 4), paintFull);
 }

 /**
 * dip转px
 * @param context
 * @param dpValue
 * @return
 */
 private int dip2px(Context context, float dpValue) {
 final float scale = context.getResources().getDisplayMetrics().density;
 return (int) (dpValue * scale + 0.5f);
 }

 /**
 * 获取"正"的高度
 *
 * @return
 */
 private float getTextH() {
 Paint pFont = new Paint();
 Rect rect = new Rect();
 //返回包围整个字符串的最小的一个Rect区域
 pFont.getTextBounds("正", 0, 1, rect);
 return rect.height();
 }

 /**
 * 获取"正"的宽度
 *
 * @return
 */
 private float getTextW() {
 Paint pFont = new Paint();
 Rect rect = new Rect();
 //返回包围整个字符串的最小的一个Rect区域
 pFont.getTextBounds("正", 0, 1, rect);
 return rect.width();
 }
}

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

(0)

相关推荐

  • Android自定义View实现圆弧进度效果

    前言:Android开发中,自定义View实现自己想要的效果已成为一项必备的技能,当然自定义View也是Android开发中比较难的部分,涉及到的知识有Canvas(画布),Paint(画笔)等,自定义控件分为三种:一是直接继承自View,完全的自定义:二是在原有控件的基础上进行改造,达到自己想要的效果:还有一种就是自定义组合控件,将已有的控件根据自己的需要进行组合实现的效果.本人对自定义View也是一知半解,简单记录下自己学习自定义View(继承自View)的过程,方便日后翻阅. 技术实现 1

  • Android TextView(圆弧)边框和背景实例详解

     Android TextView 圆弧 效果图: 布局代码: <TextView android:id="@+id/product_tag" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:singleLine="true" androi

  • 一个简单的Android圆弧刷新动画

    之前刷贴吧的时候看到的贴吧的刷新动画,就是一个圆弧旋转的动画,感觉挺好看的,就抽空实现了一下. 最终的结果是这样的: 从上图中可以看出,动画的效果是三段圆弧进行旋转,同时弧度也在逐渐增大缩小,这里采用的是在onDraw中绘制三段圆弧. // 绘制圆弧 mPaint.setColor(mTopColor); canvas.drawArc(left, top, right, bottom, startAngle, sweepAngle, false, mPaint); mPaint.setColor

  • Android 自定义球型水波纹带圆弧进度效果(实例代码)

    需求 如下,实现一个圆形水波纹,带进度,两层水波纹需要渐变显示,且外围有一个圆弧进度. 思路 外围圆弧进度:可以通过canvas.drawArc()实现.由于圆弧需要实现渐变,可以通过给画笔设置shader(SweepGradient)渲染,为了保证圆弧起始的颜色值始终一致,需要动态调整shader的参数.具体参见 SweepGradient(centerX.toFloat(), centerY.toFloat(), circleColors[0], floatArrayOf(0f, value

  • Android使用ImageView 制作透明圆弧实例代码

    这几天因为项目需求,需要在ImageView上面叠加一层透明圆弧,并且在沿着圆弧的方向显示相应的文字,效果如下图所示: 拿到这个需求,首先想到的是自定义一个ImageView来实现此功能,即在onDraw()中绘制圆弧和文字.同时因为要保证圆弧的位置可以任意摆放,圆弧的颜色.透明度以及文字大小.颜色等都是可控的,所以增加了一些自定义属性.实现代码非常简单,如下: 1.自定义ImageView: package com.chunk.customviewsdemo.views.ArcImageVie

  • 利用Android画圆弧canvas.drawArc()实例详解

    前言 在学习android中图形图像处理技术这部分内容时,对绘制圆弧函数canvas.drawArc()的用法.参数含义及画图原理很是不理解,在网上搜索了一些,加上自己的理解,在此做个小总结,下面来一起看看吧. 示例代码 public void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint) { drawArc(oval.left,

  • Android实现渐变色的圆弧虚线效果

    首先来看看效果图: 1,SweepGradient(梯度渲染) public SweepGradient (float cx, float cy, int[] colors, float[] positions) 扫描渲染,就是以某个点位中心旋转一周所形成的效果!参数依次是: cx:扫描的中心x坐标 cy:扫描的中心y坐标 colors:梯度渐变的颜色数组 positions:指定颜色数组的相对位置 public static final int[] SWEEP_GRADIENT_COLORS

  • Android 自定View实现仿QQ运动步数圆弧及动画效果

    在之前的Android超精准计步器开发-Dylan计步中的首页用到了一个自定义控件,和QQ运动的界面有点类似,还有动画效果,下面就来讲一下这个View是如何绘制的. 1.先看效果图 2.效果图分析 功能说明:黄色的代表用户设置的总计划锻炼步数,红色的代表用户当前所走的步数. 初步分析:完全自定义View重写onDraw()方法,画圆弧. 3.画一个圆弧必备知识 在Canvas中有一个画圆弧的方法 drawArc(RectF oval, float startAngle, float sweepA

  • Android自定义View绘制彩色圆弧

    本文实例为大家分享了Android自定义View绘制彩色圆弧的具体代码,供大家参考,具体内容如下 效果如下: 自定义View代码如下: package com.example.yan; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; i

  • Android自定义View绘制贝塞尔曲线中小红点的方法

    目录 前言 需求 效果图 代码 主要问题 简单画法 使用贝塞尔曲线 前言 上一篇文章用扇形图练习了一下安卓的多点触控,实现了单指旋转.二指放大.三指移动,四指以上同时按下进行复位的功能.今天这篇文章用很多应用常见的小红点,来练习一下贝塞尔曲线的使用. 需求 这里想法来自QQ的拖动小红点取消显示聊天条数功能,不过好像是记忆里的了,现在看了下好像效果变了.总而言之,就是一个小圆点,拖动的时候变成水滴状,超过一定范围后触发消失回调,核心思想如下: 1.一个正方形view,中间是小红点,小红点距离边框有

  • Android自定义view绘制表格的方法

    本文实例为大家分享了Android自定义view绘制表格的具体代码,供大家参考,具体内容如下 先上效果图 平时很少有这样的表格需求,不过第一想法就是自定义view绘制表格,事实上我确实是用的canvas来绘制的,整个过程看似复杂,实为简单,计算好各个点的坐标后事情就完成一半了.不废话show code import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; imp

  • Android自定义View绘制贝塞尔曲线的方法

    本文实例为大家分享了Android自定义View绘制贝塞尔曲线的具体代码,供大家参考,具体内容如下 在平面内任选 3 个不共线的点,依次用线段连接. 在第一条线段上任选一个点 D.计算该点到线段起点的距离 AD,与该线段总长 AB 的比例. 根据上一步得到的比例,从第二条线段上找出对应的点 E,使得 AD:AB = BE:BC. 连接这两点 DE. 从新的线段 DE 上再次找出相同比例的点 F,使得 DF:DE = AD:AB = BE:BC. 到这里,我们就确定了贝塞尔曲线上的一个点 F.接下

  • Android自定义View绘制居中文本

    本文实例为大家分享了Android自定义View绘制居中文本的具体代码,供大家参考,具体内容如下 自定义view的步骤: 1.自定义View的属性2.在View的构造方法中获得我们自定义的属性3.重写onMesure(非必须)4.重写onDraw 1.自定义View的属性,首先在res/values/ 下建立一个attrs.xml , 在里面定义我们的属性,只定义三个,有文本.颜色和字体大小: <!--CustomTextView-->     <declare-styleable na

  • Android自定义View绘制贝塞尔曲线实现流程

    目录 前言 二阶贝塞尔曲线 三阶贝塞尔曲线 前言 对于Android开发,实现贝塞尔曲线还是比较方便的,有对应的API供你调用.由于一阶贝塞尔曲线就是一条直线,实际没啥多大用处,因此,下面主要讲解二阶和三阶. 二阶贝塞尔曲线 在Android中,使用quadTo来实现二阶贝塞尔 path.reset() path.moveTo(startX, startY) path.quadTo(currentX, currentY, endX, endY) canvas.drawPath(path, cur

  • Android自定义View绘制随机生成图片验证码

    本篇文章讲的是Android自定义View之随机生成图片验证码,开发中我们会经常需要随机生成图片验证码,但是这个是其次,主要还是想总结一些自定义View的开发过程以及一些需要注意的地方. 按照惯例先看看效果图: 一.先总结下自定义View的步骤: 1.自定义View的属性 2.在View的构造方法中获得我们自定义的属性 3.重写onMesure 4.重写onDraw 其中onMesure方法不一定要重写,但大部分情况下还是需要重写的 二.View 的几个构造函数 1.public CustomV

  • Android自定义View绘制的方法及过程(二)

    上一篇<Android 自定义View(一) Paint.Rect.Canvas介绍>讲了最基础的如何自定义一个View,以及View用到的一些工具类.下面讲下View绘制的方法及过程 public class MyView extends View { private String TAG = "--------MyView"; private int width, height; public MyView(Context context, AttributeSet a

  • Android自定义View绘制四位数随机码

    现在有这样一个需求,实现显示随机随机数可能在代码中直接很简单的就实现了,但是现在我们直接自定义View来实现这个效果,那么我们来分析一波吧,我们允许开发者自己设置这个textview的大小,颜色,和初始四位随机数的文字,那么我们需要提供自定义属性,好吧,首先把自定义属性的简单使用介绍一下吧: 首先在res/values文件夹下建利attrs.xml文件,由于这次我们功能决定我们要提供三个自定义属性,分别是textTitle String类型的,textColor是color类型的,textSiz

  • 自定义滑动按钮为例图文剖析Android自定义View绘制

    自定义View一直是横在Android开发者面前的一道坎. 一.View和ViewGroup的关系 从View和ViewGroup的关系来看,ViewGroup继承View. View的子类,多是功能型的控件,提供绘制的样式,比如imageView,TextView等,而ViewGroup的子类,多用于管理控件的大小,位置,如LinearLayout,RelativeLayout等,从下图可以看出 从实际应用中看,他们又是组合关系,我们在布局中,常常是一个ViewGroup嵌套多个ViewGro

随机推荐