日常搬砖,假装写一个圆形倒计时

最近搬砖 遇到一个问题,就是启动页广告,有广告 当然有倒计时啦,问题来了。效果图上面应该是圆形的,中间填充文字。

思路很简单,继承View,重写onDraw。然后开一个子线程用于修改数据,然后写一个接口用于回调。

因为是圆形的倒计时,所以需要使用canvas.drawArc();

然后内容设置为填充,然后消除锯齿,再然后是绘制文字。

/**
* 倒计时控件
*/
public class CountdownView extends View {
  float time=5;
  float nowTime=0;
  public CountdownView setTime(float time) {
      this.time = time*1000;
      return this;
  }

  public void start(){
      //刷新重新绘制
      new Thread(new Runnable() {
          @Override
          public void run() {
              while (nowTime<=time){
                  try {
                      //刷新
                      postInvalidate();
                      Thread.sleep(200);
                      nowTime=nowTime+200;
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
              //执行完成后回调界面
              if (overCallBack!=null){
                  overCallBack.onOver();
              }
          }
      }).start();
  }

  public CountdownView(Context context) {
      super(context);
  }

  public CountdownView(Context context, @Nullable AttributeSet attrs) {
      super(context, attrs);
  }

  public CountdownView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
      super(context, attrs, defStyleAttr);
  }
  String TAG="倒计时:";
  Paint paint;
  @Override
  protected void onDraw(Canvas canvas) {
      super.onDraw(canvas);
      if (paint==null){
          paint = new Paint();
          paint.setAntiAlias(true);//消除锯齿
      }
      paint.setStyle(Paint.Style.FILL);//默认绘图为填充模式
      int canvasWidth = getWidth();
      int cx=canvasWidth/2;//圆心坐标
      int r=cx-10;

      /**
       * 用于定义的圆弧的形状和大小的界限, 界限的计算:就是以外圆的正切圆的方式计算出,左上,右下的坐标值
       * 有了中心点的坐标值cx,cy,也有了半径r那么
       * left=cx-外圆的半径
       * top=cy-外圆的半径
       * right=cx+外圆的半径
       * bottom=cy+外圆的半径
       */
      paint.setColor(Color.parseColor("#ff0077"));
      RectF rectF = new RectF(cx-r, cx-r, cx+r, cx+r);
      //RecF 定义椭圆的形状 startAngle  起始角度,sweepAngle指的是从startAngle开始沿着钟表的顺时针方向旋转扫过的角度
      //useCenter是个boolean值,如果为true,表示在绘制完弧之后,用椭圆的中心点连接弧上的起点和终点以闭合弧;如果值为false,表示在绘制完弧之后,弧的起点和终点直接连接,不经过椭圆的中心点。
      float angle=(nowTime/time)*360;
      canvas.drawArc(rectF,0, angle,true,paint);
      int  date= (int) ((time-nowTime)/1000);
      paint.setTextSize(Tools.dp2px(getContext(),14));
      paint.setColor(Color.parseColor("#ffffff"));
      //获取到文本的宽高
      int textWidth = CanvasUtils.calcTextWidth(paint, date + "");
      int textHeight = CanvasUtils.calcTextHeight(paint, date + "");
      //计算出文本描述的位置
      int tx=cx-(textWidth/2);
      int ty=cx+(textHeight/2);
      canvas.drawText(date+"",tx,ty,paint);

  }
  OverCallBack overCallBack;

  public void setOverCallBack(OverCallBack overCallBack) {
      this.overCallBack = overCallBack;
  }

  public interface OverCallBack{
     void onOver();
  }

上面使用到的工具方法:
···
private static Rect mCalcTextHeightRect = new Rect();
/**
* dp转px
*
* @param context
* @param dp
* @return
/
public static int dp2px(Context context, int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
}
/
*
* 通过画布预设获取当前文本的宽度
* @param paint
* @param demoText
* @return
/
public static int calcTextWidth(Paint paint, String demoText) {
return (int) paint.measureText(demoText);
}
/
*
* 通过 画布预设 获取当前文本的高度
* @param paint
* @param demoText
* @return
*/
public static int calcTextHeight(Paint paint, String demoText) {

    Rect r = mCalcTextHeightRect;
    r.set(0,0,0,0);
    paint.getTextBounds(demoText, 0, demoText.length(), r);
    return r.height();
}

···

你可能感兴趣的:(日常搬砖,假装写一个圆形倒计时)