android自定义view分区域点击的圆饼图(区域个数比例根据数据源动态改变)

转载请标明出处,欢迎评论探讨和指出不足之处~

效果图:

android自定义view分区域点击的圆饼图(区域个数比例根据数据源动态改变)_第1张图片


实现效果:可根据数据源的改变来动态绘制不同比例的图,并实现分区域点击效果

文末会附上工程下载链接


思路:

将360度根据比例分配给各类型数据

以-90为起点,根据比例来画第一个扇形区域,并将此扇形的末尾弧度设置为下一个扇形的起始弧度

android自定义view分区域点击的圆饼图(区域个数比例根据数据源动态改变)_第2张图片


关键点为判断点击区域:

/**
 *    4 |  1
 * -----|-----
 *    3 |  2
 * 圆被分成n(mPieDataList.size())等份,判断点击在圆的哪一部分
 */
private int touchOnWhichPart(MotionEvent event) {
    float x = event.getX();
    float y = event.getY();
    int mWhich = 1000;//错误码
    double a=0;//-90的夹角
    float sum = 0;//所占比例和
    float newRadius = mRadius+TOFRAME;//用来参与计算的半径+间距
    //在圆内
    if(Math.pow(x-newRadius,2)+Math.pow(y-newRadius,2)<=Math.pow(mRadius,2)){
        if(event.getX()>newRadius){
            //圆的右半部
            if(event.getY()>newRadius){
                //圆的下半部(综上:右下  0-90)
                a = Math.PI/2+Math.atan(Double.parseDouble(String.valueOf((y-newRadius)/(x-newRadius))));
            }else {
                //右上(-90-0)
                a = Math.atan(Double.parseDouble(String.valueOf((x-newRadius)/(newRadius-y))));
            }
        }else {
            //圆的左半部
            if(event.getY()>newRadius){
                //圆的下半部(综上:左下 90-180)
                a = Math.PI+Math.atan(Double.parseDouble(String.valueOf((newRadius-x)/(y-newRadius))));
            }else {
                //左上  180-270
                a = 2*Math.PI - Math.atan(Double.parseDouble(String.valueOf((newRadius-x)/(newRadius-y))));
            }
        }

        for (int i = 0; i < mPieDataList.size(); i++) {
            if(i<mPieDataList.size()-1)
            {
                sum+=getProportion(i);
            }else
            {
                sum =1;
            }

            if((a/(2*Math.PI))<=sum)
            {
                mWhich = i;
                break;
            }
        }

    }

    return mWhich;
}


1.确认当前点击位置与-90°(起始位置)的夹角a

2.遍历list,先判断a是否小于第一个扇形的弧度(即i=0时),如果小于,则点击区域在第一个扇形内,即which=0;

如果不在,则当i=1时,sum为第一个扇形+第二个扇形弧度,此时判断a与sum大小关系,如果a<=sum,则点击区域在第二个扇形内,即which=1;如果a>sum,则继续判断i=2时......;

注意,因为计算比例有误差,所以到最后一个圆弧时,手动设置sum=1;

代码中的注释都很清晰,详见demo



Demo下载链接



 
  

你可能感兴趣的:(自定义view)