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

先让大家看一下效果图:

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

定制的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等属性。





希望对大家有所帮助。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值