Esempio n. 1
0
  /** 此时 获取控件的 宽高 onSizeChanged 在ondraw之前调用 一般 onSizeChanged调用之后可以认为 (在非onDraw中)控件显示了 */
  @Override
  protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    Log.i("显示控件前设置变量代码执行顺序", "onSizeChanged(int w, int h, int oldw, int oldh)");

    width = getWidth();
    height = getHeight();
    just = width > height ? height : width;
    maxb = width < height ? height : width;
    centX = width * 1f / 2;
    centY = height * 1f / 2;

    // 防止 突出扇形突出过大
    // pointPieOut = just/2-padings;
    pointPieOut = pointPieOut > padings ? padings : pointPieOut;
    // 提示线突出饼图至少20 根据外圆的大小可调饼图的半径
    if (padings - lpading < TsOut) {
      padings = (int) (lpading - TsOut);
      // lpading = padings - TsOut;
    }

    pieRadius = just / 2 - padings;

    // 初始化一些画笔设置 可以外部改变的变量的初始化不要放在构造函数中
    // 设置间隔画笔风格
    paintInter.setStyle(Style.STROKE);
    paintInter.setColor(pieInterColor);

    // 画笔的宽度怎么画 与画笔宽度为0 相比 就是在画笔宽度为0的基础上左右各加粗宽度的一半
    paintInter.setStrokeWidth(pieInterWidth);

    // 当背景为透明的时候 获取布局的背景色
    if (Integer.MAX_VALUE == backColor) {
      backColor = getBackColor(); // ondraw也无法拿到布局中设置的背景色
      // backColor = Color.RED;
    }

    // ==================================饼图的展现动画=从这里触发====外界无论设置啥变量最后都会走到这======================================
    // 内往外 的展现动画 需要在此处出发,,因为这个动画 需要先获取到just
    if (pieData.size() != 0) {
      // =================设置完数据后 显示到界面==========================
      if (!showPieAnimation) {
        postInvalidate();
        return;
      }
      aniShowPie();
    }
  }
Esempio n. 2
0
  @Override
  protected void onDraw(Canvas canvas) {

    //		Log.i("显示控件前设置变量代码执行顺序", "onDraw");

    // 无论控件 那边大 都在中间的正方形画饼图
    float mWidth = 0; // 宽比高宽多少
    float mHeight = 0; // 高比宽高多少

    // 画背景
    mPaint.setColor(backColor);
    RectF back = new RectF(0, 0, width, height);

    canvas.drawRect(back, mPaint);
    if (width > height) {
      mWidth = width - height;
    } else {
      mHeight = height - width;
    }

    // TODO 提示线突出饼图至少20
    if (padings - lpading < TsOut) {
      lpading = padings - TsOut;
    }
    RectF oval;
    if (fillOut) {
      // 画扇形所需要的 矩形======扇形==从内往外 变大==所用=同时也是最终扇形所用的矩形============
      oval =
          new RectF(centX - fillouting, centY - fillouting, centX + fillouting, centY + fillouting);
    } else {
      // ========= 画扇形所需要的 矩形===========
      oval =
          new RectF(
              padings + mWidth / 2,
              padings + mHeight / 2,
              width - padings - mWidth / 2,
              height - padings - mHeight / 2);
    }

    // 画上辅助矩形
    // Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    // paint.setStyle(Style.STROKE);
    // paint.setColor(Color.RED);
    // canvas.drawRect(oval, paint);

    // onsizechange已经获取了  。当高大于宽的时候 mwidth=0
    //		pieRadius = width / 2 - padings - mWidth / 2;

    // 画饼图扇形========== 间隔 ============= 所需要的 矩形
    RectF ovalInter =
        new RectF(
            padings - pieInterWidth / 2 + mWidth / 2,
            padings - pieInterWidth / 2 + mHeight / 2,
            width - padings + pieInterWidth / 2 - mWidth / 2,
            height - padings + pieInterWidth / 2 - mHeight / 2);

    // 画辅助矩形
    // paint.setColor(Color.BLUE);
    // canvas.drawRect(ovalInter, paint);

    // TODO
    // 将 提示线的起点 设定到 饼图半径的一半处
    if (nRadius == 1) {
      nRadius = pieRadius / 2;
      Log.d("提示线起点", "将 提示线的起点 设定到 饼图半径的一半处:" + nRadius);
    }
    for (int i = 0; i < pieData.size(); i++) {
      eachPie pie = pieData.get(i);

      mPaint.setColor(pie.getPieColor());

      // 把每个扇形的起止角度 限定在360之内 方便
      float startPie = pie.getStartAngle() + degrees;
      startPie = startPie > 360 ? startPie - 360 : startPie;
      startPie = startPie < 0 ? startPie + 360 : startPie;
      float start = startPie;
      float end = startPie + pie.getSweepAngle();
      end = end > 360 ? end - 360 : end;
      end = end < 0 ? end + 360 : end;

      // // 画 特殊角度处 突出的扇形
      // if (specialAngle > 0) {
      // //在这里 判断特殊角的话 需要每次都新建RectF对象 但是不需要多画 一个扇形
      // oval = new RectF(padings + mWidth / 2, padings + mHeight / 2,
      // width - padings - mWidth / 2, height - padings - mHeight / 2);
      // if (end > specialAngle && start < specialAngle) {
      // oval = new RectF(padings + mWidth / 2 - pointPieOut,
      // padings + mHeight / 2 - pointPieOut, width
      // - padings - mWidth / 2 + pointPieOut,
      // height - padings - mHeight / 2 + pointPieOut);
      // }
      // if (end < start) {
      // if (end > specialAngle || start < specialAngle) {
      // oval = new RectF(padings + mWidth / 2 - pointPieOut,
      // padings + mHeight / 2 - pointPieOut, width
      // - padings - mWidth / 2 + pointPieOut,
      // height - padings - mHeight / 2 + pointPieOut);
      // }
      // }
      // }

      // =============== 画 饼图的扇形=====================
      canvas.drawArc(oval, startPie, pie.getSweepAngle(), true, mPaint);

      // 当饼图的间隔线宽度==========不为0 的时候 才画========间隔线====================
      if (pieInterWidth != 0) {
        // TODO  float和int数据相比较是否相等 要允许误差存在
        if ((fillOut ? Math.abs(fillouting - pieRadius) < 0.1 : true)) {
          // 当 内往外显示 饼图的时候 变大过程不显示间隔线,饼图完整显示后才画 间隔线
          // 在没执行 内往外的动画 时  一直显示 间隔线
          // 画间隔
          canvas.drawArc(ovalInter, startPie, pie.getSweepAngle(), true, paintInter);
          //					r
        }
      }

      // =====画选中=====的扇形的效果 ========当这个为true的时候 特殊角放大的扇形失效============
      if (PieSelector) {
        specialAngle = 0;
        if (clickPosition == i) {
          if ("down".equals(action)) {
            // 按下时 选择的扇形变小 无法变小 因为我是在原来饼图的上面画了这个特殊的扇形的
            drawSpecialPie(canvas, mWidth, mHeight, pie, startPie, -pointPieOut);
          } else if ("up".equals(action)) {
            // 提起是 选中的扇形变大
            drawSpecialPie(canvas, mWidth, mHeight, pie, startPie, pointPieOut);
          }
        }
      }
      // = 画 =====特殊角度处===== 突出的扇形 ======当需要的时候new出新的RectF 其实是在饼图上一层多画了一个突出的扇形=========
      if (specialAngle > 0) {
        if ((end > specialAngle && start < specialAngle)
            || (end > specialAngle || start < specialAngle) && (end < start)) {
          // 设置监听
          if (specialPielistener != null) {
            specialPielistener.onSpecialPie(i, pieData.get(i));
          }
          specialPosition = i;
          // 画突出扇形
          float outORin = pointPieOut;
          drawSpecialPie(canvas, mWidth, mHeight, pie, startPie, outORin);
        }
      }
    }

    super.onDraw(canvas); // 先画父类提示线条   //或者放最后 通过修改画提示线的颜色 来让提示线在展示动画之后出现

    // ==================================饼图的展现动画===========================================
    if (!fillOut && showPieAnimation) { // 不执行fillOut动画 同时 允许出现饼图展现动画 则执行扇形扫描动画
      if (!hideAniCircle) { // 扇形动画完后会 变成条线 所以执行完 要去掉这个扇形
        // 画最顶层的 白色扇形 360度的 用于展现饼图慢慢展开的效果
        mPaint.setColor(backColor);
        // 画扇形所需要的 矩形
        RectF oval4 = new RectF(-maxb, -maxb, maxb + maxb, maxb + maxb);
        //				RectF oval4 = new RectF(mWidth / 2, mHeight / 2, just + mWidth / 2,
        //						just + mHeight / 2);
        canvas.drawArc(oval4, start4, sweep4, true, mPaint);
      }
    }
    //		super.onDraw(canvas);// 通过修改画提示线的颜色 来让提示线在展示动画之后出现
  }