Android 如何画圆饼图来表示智能机的市场份额

原创 2013年12月03日 18:27:49

先让大家看一下效果图:

智能机的份额可能不太准确,仅仅是举例说明一下:

定制的View代码如下:


/**
 *饼状图
 *
 * @author caicai
 *
 */

@SuppressLint("ResourceAsColor")
public class RoundDistributionView extends View {

    /**
     * 饼状图的开始位置
     */

    private int beginDegree;

    /**
     * 画笔对象的引用
     */

    private Paint paint;
    
    

    /**
     * 写文字的画笔引用
     */

    private Paint textPaint;
    /**
     * 圆环进度的颜色
     */

    /**
     * 中间进度百分比的字符串的颜色
     */
    private int textColor;

    /**
     * 中间进度百分比的字符串的字体
     */
    private float textSize;

    private String[] distributionStrings = { "Android", "IOS", "WinPhone",
            "Others" };

    private int[] distributionPercents = { 60, 10, 10,20 };

    private int[] colors = { Color.RED, Color.BLUE, Color.GREEN};


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

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

    public RoundDistributionView(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);

        paint = new Paint();
        
        setDistributionStrings(getResources().getStringArray(R.array.name_distribution));
        setDistributionPercents(getResources().getIntArray(R.array.percent_distribution));
        setColors(getResources().getIntArray(R.array.colors));

        TypedArray mTypedArray = context.obtainStyledAttributes(attrs,
                R.styleable.RoundProgressBar);

        // 获取自定义属性和默认值
        textColor = mTypedArray.getColor(
                R.styleable.RoundProgressBar_textColor, Color.GREEN);
        textSize = mTypedArray.getDimension(
                R.styleable.RoundProgressBar_textSize, 16);
        beginDegree = mTypedArray.getInt(
                R.styleable.RoundProgressBar_beginDegree, 0);

        mTypedArray.recycle();

        textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        textPaint.setTextSize(textSize);
        textPaint.setColor(textColor);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        /**
         * 得到圆的圆心和半径
         */
        int centre = getWidth() / 2; // 获取圆心的x坐标
        int radius = centre; // 圆环的半径
        paint.setStyle(Paint.Style.FILL); // 设置空心
        paint.setAntiAlias(true); // 消除锯齿
        canvas.drawCircle(centre, centre, radius, paint);

        Log.e("log", centre + "");

        /**
         * 画圆弧,画扇形
         */

        // 设置扇型是实心
        RectF oval = new RectF(centre - radius, centre - radius, centre
                + radius, centre + radius); // 用于定义的圆弧的形状和大小的界限

            paint.setStyle(Paint.Style.FILL_AND_STROKE);
            for (int i = 0; i < colors.length; i++) {
                paint.setColor(colors[i]);
                int startPosition = 0;
                int endPoisition = 0;
                for (int j = 0; j < i; j++) {
                    startPosition += distributionPercents[j];
                    endPoisition += distributionPercents[j];
                }
                endPoisition += distributionPercents[i];
                Log.e("log", "开始度数====" + 360 * startPosition / 100 + " 弧度===="
                        + 360 * distributionPercents[i] / 100 + " 颜色:" + i);
                canvas.drawArc(oval, beginDegree + 360 * startPosition / 100,
                        360 * distributionPercents[i] / 100, true, paint); // 根据进度画圆弧
                /**
                 * 写市场份额百分比
                 */
                textPaint.setStrokeWidth(0);
                textPaint.setTypeface(Typeface.DEFAULT_BOLD); // 设置字体
                String displayText = distributionStrings[i] + ":"
                        + distributionPercents[i] + "%";
                float textWidth = textPaint.measureText(displayText); // 测量字体宽度,我们需要根据字体的宽度设置在扇型的平分线的中点
                int middleDegree = beginDegree + 360
                        * (startPosition + endPoisition) / 2 / 100;
                float positionX = ((float) (centre - textWidth / 2.0 + radius
                        * Math.cos(Math.toRadians(middleDegree)) / 2.0));
                float positionY = (float) (centre + textSize / 2.0 + radius
                        * Math.sin(Math.toRadians(middleDegree)) / 2.0);
                //Math.toRadians(middleDegree) 把度数转化成PI 360度等于2*PI 这条特别主要千万别忘了用这个函数Math.toRadians
                canvas.drawText(displayText, positionX, positionY, textPaint);
        }

    }
    
    public int[] getColors() {
        return colors;
    }

    public void setColors(int[] colors) {
        this.colors = colors;
    }

    public int getTextColor() {
        return textColor;
    }

    public void setTextColor(int textColor) {
        this.textColor = textColor;
    }

    public float getTextSize() {
        return textSize;
    }

    public void setTextSize(float textSize) {
        this.textSize = textSize;
    }

    public int getBeginDegree() {
        return beginDegree;
    }

    public void setBeginDegree(int beginDegree) {
        this.beginDegree = beginDegree;
    }

    public String[] getDistributionStrings() {
        return distributionStrings;
    }

    public void setDistributionStrings(String[] distributionStrings) {
        this.distributionStrings = distributionStrings;
    }

    public int[] getDistributionPercents() {
        return distributionPercents;
    }

    public void setDistributionPercents(int[] distributionPercents) {
        this.distributionPercents = distributionPercents;
    }

}


attrs.xml文件(此文件在values文件夹下面)的内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <declare-styleable name="RoundProgressBar">  
        <attr name="textColor" format="color" />  
        <attr name="textSize" format="dimension" />
        <attr name="beginDegree" format="integer"></attr>
    </declare-styleable>
</resources>


在strings.xml文件里面加入如下内容:

 <integer-array
        name="percent_distribution">
        <item>65</item>
        <item>25</item>
        <item>15</item>
    </integer-array>
    <string-array name="name_distribution">
        <item >Android</item>
        <item >IOS</item>
        <item >Others</item>
    </string-array>
    <array name="colors">
        <item>#FFFF0000</item>
        <item>#FF0000FF</item>
        <item>#FF00FF00</item>
    </array>


注意这三个数组的个数多少是一致的,第一个数组各个item的值之和为100(各自的市场份额百分比),第二个数组各自智能手机的名称,第三个数组为自己扇型图的背景色。


主Activity的layout文件内容如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:round_custom="http://schemas.android.com/apk/res/你的包名"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <你的包名.RoundDistributionView
        android:layout_height="400dip"
        android:layout_width="400dip"
        android:layout_margin="40dip"
        round_custom:textColor="#FFFFFFFF"
        round_custom:beginDegree="90"
        
        />

</RelativeLayout>


注意上面的红色字体,xmlns:round_custom="http://schemas.android.com/apk/res/你的包名"  round_custom是定制的前缀,只有在上面的attrs.xml文件中定义的属性才可以,如textColor,textSize,beginDegree等属性。





希望对大家有所帮助。


最近项目里碰上了饼图,顺便整理了下几种Android饼图,以作参考

林林总总,大概用了三种方式来实现饼图          第一种:自定义一个piechart,亲自来画一个饼图,归根结底还是参照老外的思路,但是还是有自己的一点想法在里面,先上代码: import ...
  • zhao980919517
  • zhao980919517
  • 2016年05月24日 11:28
  • 4526

使用jQuery插件Flot,绘制饼图

1、使用前,引用需引用: 2、代码如下: $(window).load(function(){ drawPie(); }); var drawPie = function()...
  • Niceplay150928
  • Niceplay150928
  • 2016年12月23日 15:05
  • 508

MPAndroidChart使用一之圆饼图

MPAndroidChart是一款基于Android的开源图表库,MPAndroidChart不仅可以在Android设备上绘制各种统计图表,而且可以对图表进行拖动和缩放操作,应用起来非常灵活。MPA...
  • Androidtalent
  • Androidtalent
  • 2016年07月24日 15:00
  • 1550

Android 自定义view画圆

今天自定义view画圆,使用到的就是Android也给我们提供了这两样东西:Paint和Canvas,由于在代码中都有对使用方法的介绍 我也不多说,来看自定义View的代码: package co...
  • haiwei15
  • haiwei15
  • 2016年09月13日 15:25
  • 6996

自定义View学习-绘制一个简单的圆

想把平时学到的关于自定义View的一些东西记录下来,从最基本的慢慢往难学吧。这篇是简单的不能再简单的绘制,算是一个入门吧。做了两个,一个是就显示圆。还有一个是绘制的圆根据手指滑动的位置来移动。并且圆的...
  • wangbin_learn
  • wangbin_learn
  • 2016年04月26日 16:44
  • 1604

手撸一个Android饼状图表(空心圆)

以前写过一篇博客 手撸一个Android饼状图表 自定义view中绘制了一个饼状图。项目中我们还经常用到一些饼状图是空心的圆看起来也很好看。 OK 空心圆的饼状图怎么绘制呢 ,下面就把 手撸一个A...
  • mingyunxiaohai
  • mingyunxiaohai
  • 2017年02月27日 14:34
  • 930

【整理】查看市场份额常用权威网站

1 浏览器市场份额(可切换全球和中国,以及可按pc及移动端查看) http://gs.statcounter.com/ 2 友盟指数(中国的安卓,iOS系统版本份额、品牌份额) http://ww...
  • snow_finland
  • snow_finland
  • 2016年05月16日 11:36
  • 2375

手撸一个Android饼状图表

要完成一个饼状图,其实就是将一个360度分成很多份,然后每一份绘制一个扇形,这些扇形加起来正好是一个整圆。 效果: android中绘制扇形 我们可以用绘制弧形的apidrawArc(RectF...
  • mingyunxiaohai
  • mingyunxiaohai
  • 2016年09月20日 17:07
  • 5273

ie上画圆饼图

概述 主要运用到CSS3的transform、js、jq实现饼状图效果 详细 代码下载:http://www.demodashi.com/demo/1...
  • findhappy117
  • findhappy117
  • 2018年02月15日 07:07
  • 51

JS画圆饼图

JS画圆饼图function DrawPieChart() { var totalvalue = value1.value/360 + value2.value/360 + value3.val...
  • mathewsking
  • mathewsking
  • 2009年01月07日 14:47
  • 406
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android 如何画圆饼图来表示智能机的市场份额
举报原因:
原因补充:

(最多只允许输入30个字)