Android自定义统计图(柱状图,折线图,饼状图)

时间:2023-02-02 23:48:34

转载自:http://blog.csdn.net/a296777513/article/details/44564197



最近由于项目需要,研究了一些统计图的做法,开始时,看了很多博文,大部分都是引用第三方的库,虽然简单,

易上手,但是功能太死板,有很多要求都是不能满足的,所以经过研究,自己使用View中的canvas重新绘图制作

统计图。首先上几张的效果图吧。


Android自定义统计图(柱状图,折线图,饼状图)Android自定义统计图(柱状图,折线图,饼状图)Android自定义统计图(柱状图,折线图,饼状图)



点击这里下载(0分下载)


一、demo的结构

一个activity中嵌套了三个fragment(v4),是用viewpager对页面进行滑动,下面是整个项目的结构:

Android自定义统计图(柱状图,折线图,饼状图)

二、核心代码

首先是MainActivity,这个demo中只使用到一个activity,现在一个activity中镶嵌多个fragment很火,

很多Android应用都在使用这个布局,例如微信,QQ等。这样做节省了空间上的浪费。

[java] view plain copy
  1. package com.example.statisticalchart;  
  2.   
  3. import android.support.v4.app.Fragment;  
  4. import android.support.v4.app.FragmentActivity;  
  5. import android.support.v4.app.FragmentPagerAdapter;  
  6. import android.support.v4.view.ViewPager;  
  7. import android.os.Bundle;  
  8.   
  9. import java.util.ArrayList;  
  10. import java.util.List;  
  11.   
  12. public class MainActivity extends FragmentActivity {  
  13.   
  14.     private ViewPager viewPager;  
  15.     private List<Fragment> fragments;  
  16.     private FragmentPagerAdapter adapter;  
  17.     // 设置是否显示动画,为了防止在创建时就开启动画,用以下三个参数做了判断,只有当看到视图后才会显示动画  
  18.     public static int flag1 = 2;  
  19.     public static int flag2 = 1;  
  20.     public static int flag3 = 1;  
  21.   
  22.     @Override  
  23.     protected void onCreate(Bundle savedInstanceState) {  
  24.         super.onCreate(savedInstanceState);  
  25.         setContentView(R.layout.activity_main);  
  26.         initView();  
  27.     }  
  28.   
  29.     private void initView() {  
  30.         viewPager = (ViewPager) findViewById(R.id.record_viewpager);  
  31.         fragments = new ArrayList<Fragment>();  
  32.         RecordPager1 recordPager1 = new RecordPager1();  
  33.         RecordPager2 recordPager2 = new RecordPager2();  
  34.         RecordPager3 recordPager3 = new RecordPager3();  
  35.         fragments.add(recordPager1);  
  36.         fragments.add(recordPager2);  
  37.         fragments.add(recordPager3);  
  38.   
  39.         adapter = new FragmentPagerAdapter(getSupportFragmentManager()) {  
  40.             @Override  
  41.             public Fragment getItem(int position) {  
  42.                 return fragments.get(position);  
  43.             }  
  44.   
  45.             @Override  
  46.             public int getCount() {  
  47.                 return fragments.size();  
  48.             }  
  49.         };  
  50.         viewPager.setAdapter(adapter);  
  51.   
  52.         viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {  
  53.             @Override  
  54.             public void onPageScrolled(int position, float positionOffset,  
  55.                     int positionOffsetPixels) {  
  56.   
  57.             }  
  58.   
  59.             @Override  
  60.             public void onPageSelected(int position) {  
  61.                 if (position == 0 && flag1 == 1) {  
  62.                     flag1 = 2;  
  63.                     fragments.get(0).onResume();  
  64.                     flag1 = 3;  
  65.                 }  
  66.                 if (position == 1 && flag2 == 1) {  
  67.                     flag2 = 2;  
  68.                     fragments.get(1).onResume();  
  69.                     flag2 = 3;  
  70.   
  71.                 }  
  72.                 if (position == 2 && flag3 == 1) {  
  73.                     flag3 = 2;  
  74.                     fragments.get(2).onResume();  
  75.                     flag3 = 3;  
  76.                 }  
  77.             }  
  78.   
  79.             @Override  
  80.             public void onPageScrollStateChanged(int state) {  
  81.   
  82.             }  
  83.         });  
  84.     }  
  85.   
  86. }  

接下来是这个项目中最主要的三个类:HistogramView、LineChartView、PinChart。这三个类继承View类,重新构图,分别画成了柱状图,折线图,饼状图,然后给出三个类的代码:

[java] view plain copy
  1. package com.example.statisticalchart;  
  2.   
  3. import android.annotation.SuppressLint;  
  4. import android.content.Context;  
  5. import android.graphics.Bitmap;  
  6. import android.graphics.BitmapFactory;  
  7. import android.graphics.Canvas;  
  8. import android.graphics.Color;  
  9. import android.graphics.Paint;  
  10. import android.graphics.Paint.Align;  
  11. import android.graphics.Rect;  
  12. import android.os.Looper;  
  13. import android.util.AttributeSet;  
  14. import android.view.MotionEvent;  
  15. import android.view.View;  
  16. import android.view.animation.Animation;  
  17. import android.view.animation.Transformation;  
  18.   
  19. public class HistogramView extends View {  
  20.   
  21.     private Paint xLinePaint;// 坐标轴 轴线 画笔:  
  22.     private Paint hLinePaint;// 坐标轴水平内部 虚线画笔  
  23.     private Paint titlePaint;// 绘制文本的画笔  
  24.     private Paint paint;// 矩形画笔 柱状图的样式信息  
  25.     private int[] progress = { 200050006000800050060009000 };// 7  
  26.                                                                             // 条,显示各个柱状的数据  
  27.     private int[] aniProgress;// 实现动画的值  
  28.     private final int TRUE = 1;// 在柱状图上显示数字  
  29.     private int[] text;// 设置点击事件,显示哪一条柱状的信息  
  30.     private Bitmap bitmap;  
  31.     // 坐标轴左侧的数标  
  32.     private String[] ySteps;  
  33.     // 坐标轴底部的星期数  
  34.     private String[] xWeeks;  
  35.     private int flag;// 是否使用动画  
  36.   
  37.     private HistogramAnimation ani;  
  38.   
  39.     public HistogramView(Context context) {  
  40.         super(context);  
  41.         init();  
  42.     }  
  43.   
  44.     public HistogramView(Context context, AttributeSet attrs) {  
  45.         super(context, attrs);  
  46.         init();  
  47.     }  
  48.   
  49.     private void init() {  
  50.   
  51.         ySteps = new String[] { "10k""7.5k""5k""2.5k""0" };  
  52.         xWeeks = new String[] { "周一""周二""周三""周四""周五""周六""周日" };  
  53.         text = new int[] { 0000000 };  
  54.         aniProgress = new int[] { 0000000 };  
  55.         ani = new HistogramAnimation();  
  56.         ani.setDuration(2000);  
  57.   
  58.         xLinePaint = new Paint();  
  59.         hLinePaint = new Paint();  
  60.         titlePaint = new Paint();  
  61.         paint = new Paint();  
  62.   
  63.         // 给画笔设置颜色  
  64.         xLinePaint.setColor(Color.DKGRAY);  
  65.         hLinePaint.setColor(Color.LTGRAY);  
  66.         titlePaint.setColor(Color.BLACK);  
  67.   
  68.         // 加载画图  
  69.         bitmap = BitmapFactory  
  70.                 .decodeResource(getResources(), R.drawable.column);  
  71.     }  
  72.   
  73.     public void start(int flag) {  
  74.         this.flag = flag;  
  75.         this.startAnimation(ani);  
  76.     }  
  77.   
  78.     @SuppressLint("DrawAllocation")  
  79.     @Override  
  80.     protected void onDraw(Canvas canvas) {  
  81.         super.onDraw(canvas);  
  82.   
  83.         int width = getWidth();  
  84.         int height = getHeight() - dp2px(50);  
  85.         // 绘制底部的线条  
  86.         canvas.drawLine(dp2px(30), height + dp2px(3), width - dp2px(30), height  
  87.                 + dp2px(3), xLinePaint);  
  88.   
  89.         int leftHeight = height - dp2px(5);// 左侧外周的 需要划分的高度:  
  90.   
  91.         int hPerHeight = leftHeight / 4;// 分成四部分  
  92.   
  93.         hLinePaint.setTextAlign(Align.CENTER);  
  94.         // 设置四条虚线  
  95.         for (int i = 0; i < 4; i++) {  
  96.             canvas.drawLine(dp2px(30), dp2px(10) + i * hPerHeight, width  
  97.                     - dp2px(30), dp2px(10) + i * hPerHeight, hLinePaint);  
  98.         }  
  99.   
  100.         // 绘制 Y 周坐标  
  101.         titlePaint.setTextAlign(Align.RIGHT);  
  102.         titlePaint.setTextSize(sp2px(12));  
  103.         titlePaint.setAntiAlias(true);  
  104.         titlePaint.setStyle(Paint.Style.FILL);  
  105.         // 设置左部的数字  
  106.         for (int i = 0; i < ySteps.length; i++) {  
  107.             canvas.drawText(ySteps[i], dp2px(25), dp2px(13) + i * hPerHeight,  
  108.                     titlePaint);  
  109.         }  
  110.   
  111.         // 绘制 X 周 做坐标  
  112.         int xAxisLength = width - dp2px(30);  
  113.         int columCount = xWeeks.length + 1;  
  114.         int step = xAxisLength / columCount;  
  115.   
  116.         // 设置底部的数字  
  117.         for (int i = 0; i < columCount - 1; i++) {  
  118.             // text, baseX, baseY, textPaint  
  119.             canvas.drawText(xWeeks[i], dp2px(25) + step * (i + 1), height  
  120.                     + dp2px(20), titlePaint);  
  121.         }  
  122.   
  123.         // 绘制矩形  
  124.         if (aniProgress != null && aniProgress.length > 0) {  
  125.             for (int i = 0; i < aniProgress.length; i++) {// 循环遍历将7条柱状图形画出来  
  126.                 int value = aniProgress[i];  
  127.                 paint.setAntiAlias(true);// 抗锯齿效果  
  128.                 paint.setStyle(Paint.Style.FILL);  
  129.                 paint.setTextSize(sp2px(15));// 字体大小  
  130.                 paint.setColor(Color.parseColor("#6DCAEC"));// 字体颜色  
  131.                 Rect rect = new Rect();// 柱状图的形状  
  132.   
  133.                 rect.left = step * (i + 1);  
  134.                 rect.right = dp2px(30) + step * (i + 1);  
  135.                 int rh = (int) (leftHeight - leftHeight * (value / 10000.0));  
  136.                 rect.top = rh + dp2px(10);  
  137.                 rect.bottom = height;  
  138.   
  139.                 canvas.drawBitmap(bitmap, null, rect, paint);  
  140.                 // 是否显示柱状图上方的数字  
  141.                 if (this.text[i] == TRUE) {  
  142.                     canvas.drawText(value + "", dp2px(15) + step * (i + 1)  
  143.                             - dp2px(15), rh + dp2px(5), paint);  
  144.                 }  
  145.   
  146.             }  
  147.         }  
  148.   
  149.     }  
  150.   
  151.     private int dp2px(int value) {  
  152.         float v = getContext().getResources().getDisplayMetrics().density;  
  153.         return (int) (v * value + 0.5f);  
  154.     }  
  155.   
  156.     private int sp2px(int value) {  
  157.         float v = getContext().getResources().getDisplayMetrics().scaledDensity;  
  158.         return (int) (v * value + 0.5f);  
  159.     }  
  160.   
  161.     /** 
  162.      * 设置点击事件,是否显示数字 
  163.      */  
  164.     public boolean onTouchEvent(MotionEvent event) {  
  165.         int step = (getWidth() - dp2px(30)) / 8;  
  166.         int x = (int) event.getX();  
  167.         for (int i = 0; i < 7; i++) {  
  168.             if (x > (dp2px(15) + step * (i + 1) - dp2px(15))  
  169.                     && x < (dp2px(15) + step * (i + 1) + dp2px(15))) {  
  170.                 text[i] = 1;  
  171.                 for (int j = 0; j < 7; j++) {  
  172.                     if (i != j) {  
  173.                         text[j] = 0;  
  174.                     }  
  175.                 }  
  176.                 if (Looper.getMainLooper() == Looper.myLooper()) {  
  177.                     invalidate();  
  178.                 } else {  
  179.                     postInvalidate();  
  180.                 }  
  181.             }  
  182.         }  
  183.         return super.onTouchEvent(event);  
  184.     }  
  185.   
  186.     /** 
  187.      * 集成animation的一个动画类 
  188.      *  
  189.      * @author 李垭超 
  190.      */  
  191.     private class HistogramAnimation extends Animation {  
  192.         protected void applyTransformation(float interpolatedTime,  
  193.                 Transformation t) {  
  194.             super.applyTransformation(interpolatedTime, t);  
  195.             if (interpolatedTime < 1.0f && flag == 2) {  
  196.                 for (int i = 0; i < aniProgress.length; i++) {  
  197.                     aniProgress[i] = (int) (progress[i] * interpolatedTime);  
  198.                 }  
  199.             } else {  
  200.                 for (int i = 0; i < aniProgress.length; i++) {  
  201.                     aniProgress[i] = progress[i];  
  202.                 }  
  203.             }  
  204.             invalidate();  
  205.         }  
  206.     }  
  207.   
  208. }  


[java] view plain copy
  1. package com.example.statisticalchart;  
  2.   
  3. import android.annotation.SuppressLint;  
  4. import android.content.Context;  
  5. import android.graphics.Bitmap;  
  6. import android.graphics.BitmapFactory;  
  7. import android.graphics.Canvas;  
  8. import android.graphics.Color;  
  9. import android.graphics.Paint;  
  10. import android.graphics.Paint.Align;  
  11. import android.graphics.Path;  
  12. import android.graphics.PorterDuff;  
  13. import android.graphics.PorterDuffXfermode;  
  14. import android.graphics.Rect;  
  15. import android.util.AttributeSet;  
  16. import android.util.Log;  
  17. import android.view.View;  
  18. import android.view.animation.Animation;  
  19. import android.view.animation.Transformation;  
  20.   
  21. public class LineChartView extends View {  
  22.   
  23.     private Paint rectPaint;// 设置左侧为白色,显示数表  
  24.     private Paint hLinePaint;// 坐标轴水平内部 虚线画笔  
  25.     private Paint titlePaint;// 绘制文本的画笔  
  26.     private Paint linePaint;  
  27.     private Paint paint;// 矩形画笔 柱状图的样式信息  
  28.     private int[] text;// 折线的转折点  
  29.     int x, y, preX, preY;  
  30.     // 坐标轴左侧的数标  
  31.     private Bitmap mBitmap;  
  32.     // 坐标轴底部的星期数  
  33.     private String[] str = { "62""72""82""92""102""112""122",  
  34.             "132""142" };  
  35.   
  36.     private HistogramAnimation ani;  
  37.     private int flag;  
  38.   
  39.     public LineChartView(Context context) {  
  40.         super(context);  
  41.         init(context, null);  
  42.     }  
  43.   
  44.     public LineChartView(Context context, AttributeSet attrs) {  
  45.         super(context, attrs);  
  46.         // TODO Auto-generated constructor stub  
  47.         init(context, attrs);  
  48.     }  
  49.   
  50.     private void init(Context context, AttributeSet attrs) {  
  51.   
  52.         text = new int[] { 6554532311 };  
  53.   
  54.         ani = new HistogramAnimation();  
  55.         ani.setDuration(4000);  
  56.   
  57.         rectPaint = new Paint();  
  58.         titlePaint = new Paint();  
  59.   
  60.     }  
  61.   
  62.     @Override  
  63.     protected void onDraw(Canvas canvas) {  
  64.         super.onDraw(canvas);  
  65.         linePaint = new Paint();  
  66.   
  67.         //  
  68.         titlePaint.setAntiAlias(true);  
  69.         Rect bundle1 = new Rect();  
  70.   
  71.         Rect bundle2 = new Rect();  
  72.         hLinePaint = new Paint();  
  73.   
  74.         int perWidth = getWidth() / 10;// 将宽度分为10部分  
  75.         int hPerHeight = getHeight() / 10;// 将高度分为10部分  
  76.         rectPaint.setColor(Color.WHITE);  
  77.   
  78.         canvas.drawRect(00, dp2px(30), getHeight(), rectPaint);// 画一块白色区域  
  79.   
  80.         Path path = new Path();// 折线图的路径  
  81.         mBitmap = Bitmap.createBitmap(getWidth(), getHeight(),  
  82.                 Bitmap.Config.ARGB_8888);  
  83.         Canvas mCanvas = new Canvas(mBitmap);  
  84.   
  85.         for (int i = 0; i < 10; i++) {// 画x线,并在左侧显示相应的数值  
  86.             hLinePaint.setTextAlign(Align.CENTER);  
  87.             hLinePaint.setColor(Color.WHITE);  
  88.             y = i * hPerHeight;  
  89.             if (i == 2) {  
  90.                 hLinePaint.setStrokeWidth(4);  
  91.                 for (int j = 0; j < 10; j++) {  
  92.                     canvas.drawLine(dp2px(30) + j * perWidth, y, dp2px(28)  
  93.                             + (j + 1) * perWidth, y, hLinePaint);  
  94.                 }  
  95.                 titlePaint.setTextSize(sp2px(20));  
  96.                 titlePaint.getTextBounds(str[i - 1], 0, str[i - 1].length(),  
  97.                         bundle1);  
  98.                 canvas.drawText(str[i - 1], dp2px(25) - bundle1.width(), i  
  99.                         * hPerHeight + (bundle1.height() / 2), titlePaint);  
  100.             } else {  
  101.                 hLinePaint.setStrokeWidth(1);  
  102.                 canvas.drawLine(dp2px(30), y, getWidth(), y, hLinePaint);  
  103.                 if (i != 0) {  
  104.                     titlePaint.setTextSize(sp2px(15));  
  105.                     titlePaint.getTextBounds(str[i - 1], 0,  
  106.                             str[i - 1].length(), bundle2);  
  107.                     canvas.drawText(str[i - 1], dp2px(25) - bundle2.width(), i  
  108.                             * hPerHeight + (bundle2.height() / 2), titlePaint);  
  109.                 }  
  110.             }  
  111.   
  112.             x = i * perWidth + dp2px(30);  
  113.             if (i == 0) {  
  114.                 path.moveTo(x, text[i] * hPerHeight);  
  115.             } else {  
  116.                 path.lineTo(x, text[i] * hPerHeight);  
  117.             }  
  118.             linePaint.setColor(Color.parseColor("#bb2222"));  
  119.             linePaint.setAntiAlias(true);  
  120.   
  121.             paint = new Paint();  
  122.             paint.setColor(Color.RED);  
  123.             paint.setStyle(Paint.Style.STROKE);  
  124.             paint.setStrokeWidth(dp2px(1));  
  125.             if (i != 0) {  
  126.                 mCanvas.drawCircle(x, text[i] * hPerHeight, dp2px(3), linePaint);  
  127.             }  
  128.             paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OVER));  
  129.             mCanvas.drawPath(path, paint);  
  130.         }  
  131.   
  132.         paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));  
  133.         paint.setStyle(Paint.Style.FILL);  
  134.   
  135.         mCanvas.drawRect(preX + dp2px(30), 0, getWidth(), getHeight(), paint);  
  136.         canvas.drawBitmap(mBitmap, 00null);  
  137.         // Log.i("tag", "onDraw()1111");  
  138.     }  
  139.   
  140.     private int dp2px(int value) {  
  141.         float v = getContext().getResources().getDisplayMetrics().density;  
  142.         return (int) (v * value + 0.5f);  
  143.     }  
  144.   
  145.     private int sp2px(int value) {  
  146.         float v = getContext().getResources().getDisplayMetrics().scaledDensity;  
  147.         return (int) (v * value + 0.5f);  
  148.     }  
  149.   
  150.     public void start(int flag) {  
  151.         startAnimation(ani);  
  152.         this.flag = flag;  
  153.     }  
  154.   
  155.     /** 
  156.      * 集成animation的一个动画类 
  157.      *  
  158.      * @author  
  159.      */  
  160.     private class HistogramAnimation extends Animation {  
  161.         @Override  
  162.         protected void applyTransformation(float interpolatedTime,  
  163.                 Transformation t) {  
  164.             super.applyTransformation(interpolatedTime, t);  
  165.             if (interpolatedTime < 1.0f && flag == 2) {  
  166.                 preX = (int) ((getWidth() - dp2px(30)) * interpolatedTime);  
  167.             } else {  
  168.   
  169.                 preX = getWidth();  
  170.   
  171.             }  
  172.             invalidate();  
  173.         }  
  174.     }  
  175.   
  176. }  

[java] view plain copy
  1. package com.example.statisticalchart;  
  2.   
  3. import android.content.Context;  
  4. import android.graphics.Canvas;  
  5. import android.graphics.Color;  
  6. import android.graphics.Paint;  
  7. import android.graphics.PorterDuff;  
  8. import android.graphics.PorterDuffXfermode;  
  9. import android.graphics.Rect;  
  10. import android.graphics.RectF;  
  11. import android.util.AttributeSet;  
  12. import android.util.Log;  
  13. import android.view.View;  
  14. import android.view.animation.Animation;  
  15. import android.view.animation.Transformation;  
  16.   
  17. public class PinChart extends View {  
  18.   
  19.     static Canvas c;  
  20.     private Paint[] mPaints;  
  21.     private RectF mBigOval;  
  22.     float[] mSweep = { 0000000000 };  
  23.     private int preWidth;  
  24.     private mAnimation ani;  
  25.     private int flag;  
  26.     private int centerX;  
  27.     private int centerY;  
  28.     int valueX;  
  29.     int valueY;  
  30.   
  31.     public static float[] humidity = { 11060505040301010 };  
  32.     private String str[] = { "数据24%""数据19%""数据21%""其他18%""数据3%",  
  33.             "数据3%""数据4%""数据6%" };  
  34.   
  35.     private final String color[] = { "#2cbae7""#ffa500""#ff5b3b",  
  36.             "#9fa0a4""#6a71e5""#f83f5d""#64a300""#64ef85" };  
  37.   
  38.     public PinChart(Context context) {  
  39.         super(context);  
  40.         initView();  
  41.     }  
  42.   
  43.     public PinChart(Context context, AttributeSet atr) {  
  44.         super(context, atr);  
  45.         initView();  
  46.     }  
  47.   
  48.     private void initView() {  
  49.         ani = new mAnimation();  
  50.         ani.setDuration(2000);  
  51.     }  
  52.   
  53.     @Override  
  54.     protected void onDraw(Canvas canvas) {  
  55.         canvas.drawColor(Color.TRANSPARENT);// 设置背景颜色(透明)  
  56.         mPaints = new Paint[humidity.length];  
  57.   
  58.         for (int i = 0; i < humidity.length; i++) {  
  59.             mPaints[i] = new Paint();  
  60.             mPaints[i].setAntiAlias(true);  
  61.             mPaints[i].setStyle(Paint.Style.FILL);  
  62.             mPaints[i].setColor(Color.parseColor(color[i]));  
  63.         }  
  64.         int cicleWidth = getWidth() - dp2px(60);  
  65.         centerX = getWidth() / 2;  
  66.         centerY = dp2px(10) + cicleWidth / 2;  
  67.         preWidth = (getWidth() - dp2px(40)) / 4;  
  68.         int half = getWidth() / 2;  
  69.   
  70.         mBigOval = new RectF();// 饼图的四周边界  
  71.         mBigOval.top = dp2px(10);  
  72.         mBigOval.left = half - cicleWidth / 2;  
  73.         mBigOval.bottom = dp2px(10) + cicleWidth;  
  74.         mBigOval.right = half + cicleWidth / 2;  
  75.   
  76.         float start = -180;  
  77.         Rect bounds = new Rect();  
  78.         for (int i = 0; i < humidity.length; i++) {  
  79.             canvas.drawArc(mBigOval, start, mSweep[i], true, mPaints[i]);  
  80.             if (humidity[i] > 45) {  
  81.                 mPaints[i].setXfermode(new PorterDuffXfermode(  
  82.                         PorterDuff.Mode.SRC_OVER));  
  83.                 mPaints[i].setAntiAlias(true);  
  84.                 mPaints[i].setColor(Color.WHITE);  
  85.                 mPaints[i].getTextBounds(str[i], 0, str[i].length(), bounds);  
  86.                 mPaints[i].setTextSize(sp2px(15));  
  87.                 measureText(start + 180, humidity[i], cicleWidth / 3, i);  
  88.                 canvas.drawText(str[i], valueX - mPaints[i].measureText(str[i])  
  89.                         / 2, valueY + bounds.height() / 2, mPaints[i]);  
  90.             }  
  91.             start += humidity[i];  
  92.             int j = 1;  
  93.             int k;  
  94.             if (i < 4) {  
  95.                 j = 0;  
  96.                 k = i;  
  97.             } else {  
  98.                 j = 1;  
  99.                 k = i - 4;  
  100.             }  
  101.             mPaints[i] = new Paint();  
  102.             mPaints[i].setAntiAlias(true);  
  103.             mPaints[i].setStyle(Paint.Style.FILL);  
  104.             mPaints[i].setColor(Color.parseColor(color[i]));  
  105.             canvas.drawRect(new RectF(dp2px(20) + preWidth * k, cicleWidth  
  106.                     + dp2px(j * 30 + 20), dp2px(20) + preWidth * (k + 1),  
  107.                     cicleWidth + dp2px(50 + j * 30)), mPaints[i]);  
  108.             mPaints[i].setXfermode(new PorterDuffXfermode(  
  109.                     PorterDuff.Mode.SRC_OVER));  
  110.             mPaints[i].setAntiAlias(true);  
  111.             mPaints[i].setColor(Color.WHITE);  
  112.             mPaints[i].getTextBounds(str[i], 0, str[i].length(), bounds);  
  113.             mPaints[i].setTextSize(sp2px(15));  
  114.             canvas.drawText(str[i], dp2px(20) + preWidth * k + preWidth / 2  
  115.                     - mPaints[i].measureText(str[i]) / 2, cicleWidth  
  116.                     + dp2px(j * 30 + 20)  
  117.                     + (dp2px(30) / 2 + bounds.height() / 2), mPaints[i]);  
  118.         }  
  119.     }  
  120.   
  121.     /** 
  122.      * 显示相应区域字开始的x,y坐标 
  123.      *  
  124.      * @param start 
  125.      * @param angle 
  126.      * @param radius 
  127.      * @param i 
  128.      */  
  129.     private void measureText(float start, float angle, int radius, int i) {  
  130.         float temp = start + (angle / 2);  
  131.   
  132.         if (temp < 90) {  
  133.             valueX = (int) (centerX - Math.abs(radius  
  134.                     * Math.sin((temp / 180) * Math.PI)));  
  135.             valueY = (int) (centerY - Math.abs(radius  
  136.                     * Math.cos((temp / 180) * Math.PI)));  
  137.         } else if (temp > 90 && temp < 180) {  
  138.             temp = 180 - temp;  
  139.             valueX = centerX  
  140.                     + (int) Math  
  141.                             .abs((radius * Math.cos((temp / 180) * Math.PI)));  
  142.             valueY = centerY  
  143.                     - (int) Math  
  144.                             .abs((radius * Math.sin((temp / 180) * Math.PI)));  
  145.         } else if (temp > 180 && temp < 270) {  
  146.             temp = temp - 180;  
  147.             valueX = centerX  
  148.                     + (int) Math  
  149.                             .abs((radius * Math.cos((temp / 180) * Math.PI)));  
  150.             valueY = centerY  
  151.                     + (int) Math  
  152.                             .abs((radius * Math.sin((temp / 180) * Math.PI)));  
  153.         } else {  
  154.             temp = 360 - temp;  
  155.             valueX = centerX  
  156.                     - (int) Math  
  157.                             .abs((radius * Math.cos((temp / 180) * Math.PI)));  
  158.             valueY = centerY  
  159.                     + (int) Math  
  160.                             .abs((radius * Math.sin((temp / 180) * Math.PI)));  
  161.         }  
  162.   
  163.     }  
  164.   
  165.     private int sp2px(int value) {  
  166.         float v = getResources().getDisplayMetrics().scaledDensity;  
  167.         return (int) (value * v + 0.5f);  
  168.     }  
  169.   
  170.     private int dp2px(int value) {  
  171.         float v = getResources().getDisplayMetrics().density;  
  172.         return (int) (value * v + 0.5f);  
  173.     }  
  174.   
  175.     public void start(int flag) {  
  176.         startAnimation(ani);  
  177.         this.flag = flag;  
  178.     }  
  179.   
  180.     class mAnimation extends Animation {  
  181.         @Override  
  182.         protected void applyTransformation(float interpolatedTime,  
  183.                 Transformation t) {  
  184.             super.applyTransformation(interpolatedTime, t);  
  185.             if (interpolatedTime < 1.0f && flag == 2) {  
  186.                 for (int i = 0; i < humidity.length; i++) {  
  187.                     mSweep[i] = humidity[i] * interpolatedTime;  
  188.                 }  
  189.             } else if (flag == 1) {  
  190.                 for (int i = 0; i < humidity.length; i++) {  
  191.                     mSweep[i] = 0;  
  192.                 }  
  193.             } else {  
  194.                 for (int i = 0; i < humidity.length; i++) {  
  195.                     mSweep[i] = humidity[i];  
  196.                 }  
  197.             }  
  198.             invalidate();  
  199.         }  
  200.     }  
  201.   
  202. }  

以上都是核心代码,并不是全部的代码,起他部分的代码就不贴出来了,感兴趣的朋友可以下载来研究研究。