欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android自定义view绘制圆环占比动画

程序员文章站 2023-12-21 11:18:52
一、实现效果图 二、核心代码 1.自定义myprogressview.java package com.czhappy.effectdemo.view...

一、实现效果图

Android自定义view绘制圆环占比动画

二、核心代码

1.自定义myprogressview.java

package com.czhappy.effectdemo.view;

import android.content.context;
import android.content.res.typedarray;
import android.graphics.bitmap;
import android.graphics.bitmapfactory;
import android.graphics.canvas;
import android.graphics.color;
import android.graphics.paint;
import android.graphics.paint.fontmetrics;
import android.graphics.rect;
import android.graphics.rectf;
import android.os.handler;
import android.os.message;
import android.text.textutils;
import android.util.attributeset;
import android.view.view;

import com.czhappy.effectdemo.r;
import com.czhappy.effectdemo.utils.screenutil;


public class myprogressview extends view {

 // 画实心圆的画笔
 private paint mcirclepaint;
 // 画圆环的画笔
 private paint mringdefaultpaint;
 // 已用环的画笔
 private paint musepaint;
 // 画圆环的画笔
 private paint mringpaint;
 // 画白线的画笔
 private paint mlinepaint;
 // 画字体的画笔
 private paint mtextpaint;
 // 圆形颜色
 private int mcirclecolor;
 // 圆环颜色
 private int mringcolor;
 // 半径
 private float mradius;
 // 圆环半径
 private float mringradius;
 // 圆环宽度
 private float mstrokewidth;
 // 圆心x坐标
 private int mxcenter;
 // 圆心y坐标
 private int mycenter;
 // 字的长度
 private float mtxtwidth;
 // 字的高度
 private float mtxtheight;
 // 总进度
 private int mtotalprogress = 100;
 // 当前进度
 private int mprogress;
 // 实际展示总进度
 private int mshowprogress;
 // 已用流量
 private string usedflow;

 private context mcontext;

 private handler circlehandler = new handler(){

  public void handlemessage(message msg) {
   super.handlemessage(msg);
   if(msg.what == 1){
    int temp = (integer)msg.obj;
    setprogress(temp);
   }
  };
 };

 public myprogressview(context context, attributeset attrs) {
  super(context, attrs);
  mcontext = context;
  // 获取自定义的属性
  initattrs(context, attrs);
  initvariable();
 }

 private void initattrs(context context, attributeset attrs) {
  typedarray typearray = context.gettheme().obtainstyledattributes(attrs,
    r.styleable.taskscompletedview, 0, 0);
  mradius = typearray.getdimension(r.styleable.taskscompletedview_radius, 80);
  mstrokewidth = typearray.getdimension(r.styleable.taskscompletedview_strokewidth, 10);
  mcirclecolor = typearray.getcolor(r.styleable.taskscompletedview_circlecolor, 0xffffffff);
  mringcolor = typearray.getcolor(r.styleable.taskscompletedview_ringcolor, 0xffffffff);

  mringradius = mradius + mstrokewidth / 2;
 }

 private void initvariable() {
  //画圆画笔设置
  mcirclepaint = new paint();
  mcirclepaint.setantialias(true);//防锯齿
  mcirclepaint.setcolor(mcirclecolor);
  mcirclepaint.setstyle(paint.style.fill);

  //“使用”字画笔设置
  musepaint = new paint();
  musepaint.setantialias(true);
  musepaint.setstyle(paint.style.fill);
  musepaint.setcolor(getresources().getcolor(r.color.ticket_color));
  musepaint.settextsize(screenutil.sp2px(mcontext, 10));

  //圆环画笔设置
  mringdefaultpaint = new paint();
  mringdefaultpaint.setantialias(true);
  mringdefaultpaint.setcolor(getresources().getcolor(r.color.default_ring_color));
  mringdefaultpaint.setstyle(paint.style.stroke);
  mringdefaultpaint.setstrokewidth(mstrokewidth);

  //已使用多少圆环画笔设置
  mringpaint = new paint();
  mringpaint.setantialias(true);
  mringpaint.setcolor(mringcolor);
  mringpaint.setstyle(paint.style.stroke);
  mringpaint.setstrokewidth(mstrokewidth);

  mtextpaint = new paint();
  mtextpaint.setantialias(true);
  mtextpaint.setstyle(paint.style.fill);
  mtextpaint.setcolor(color.black);
  mtextpaint.settextsize(screenutil.sp2px(mcontext, 22));

  mlinepaint = new paint();
  mlinepaint.setcolor(color.white);


  //获取字体高度
  fontmetrics fm = mtextpaint.getfontmetrics();
  mtxtheight = (int) math.ceil(fm.descent - fm.ascent);

 }

 @override
 protected void ondraw(canvas canvas) {

  mxcenter = getwidth() / 2;
  mycenter = getheight() / 2;

  //画圆
  canvas.drawcircle(mxcenter, mycenter, mradius, mcirclepaint);

  rectf oval = new rectf();
  oval.left = (mxcenter - mringradius);
  oval.top = (mycenter - mringradius);
  oval.right = mringradius * 2 + (mxcenter - mringradius);
  oval.bottom = mringradius * 2 + (mycenter - mringradius);
  //画整圆弧
  canvas.drawarc(oval, -90, 360, false, mringdefaultpaint);
  //已使用多少圆弧
  canvas.drawarc(oval, -90, ((float) mprogress / mtotalprogress) * 360, false, mringpaint);
  //文字绘制
  string txt = mprogress + "%";
  //文字的长度
  mtxtwidth = mtextpaint.measuretext(txt, 0, txt.length());
  canvas.drawtext(txt, mxcenter - mtxtwidth / 2, mycenter + mtxtheight / 9, mtextpaint);

  rect _pb = new rect();
  string sup = "已用";
  musepaint.gettextbounds(sup, 0, sup.length(), _pb);
  int perx = mxcenter - _pb.width() / 2;
  canvas.drawtext(sup, perx, mycenter / 2, musepaint);

  if (!textutils.isempty(usedflow)) {
   musepaint.gettextbounds(usedflow, 0, usedflow.length(), _pb);
   perx = mxcenter - _pb.width() / 2;
   canvas.drawtext(usedflow, perx, (float) (mycenter + mycenter / 1.7), musepaint);
  }

  //画横线图片
  bitmap bitmap = bitmapfactory.decoderesource(getresources(), r.mipmap.circle_bottom_bg);
  perx = mxcenter - bitmap.getwidth() / 2;
  canvas.drawbitmap(bitmap, perx, (float) (mycenter + mycenter / 5), mlinepaint);
 }

 /**
  * 设置当前进度
  * @param progress
  */
 public void setprogress(int progress) {
  mprogress = progress;
  postinvalidate();
 }

 /**
  * 实际展示总进度
  * @param progress
  */
 public void setmshowprogress(int progress) {
  mshowprogress = progress;
  new thread(new circlethread()).start();
 }

 public void setusedflow(string usedflow) {
  this.usedflow = usedflow;
 }


 private class circlethread implements runnable{

  int m=0;
  int i=0;

  @override
  public void run() {
   // todo auto-generated method stub
   while(!thread.currentthread().isinterrupted()){
    try {
     thread.sleep(50);
     m++;
     message msg = new message();
     msg.what = 1;
     if(i < mshowprogress){
      i += m;
     }else{
      i = mshowprogress;
      return;
     }
     msg.obj = i;
     circlehandler.sendmessage(msg);
    } catch (interruptedexception e) {
     // todo auto-generated catch block
     e.printstacktrace();
    }
   }
  }

 }
}

2.flowactivity.java

package com.czhappy.effectdemo.activity;

import android.os.bundle;
import android.support.annotation.nullable;
import android.support.v7.app.appcompatactivity;
import android.view.view;

import com.czhappy.effectdemo.r;
import com.czhappy.effectdemo.view.myprogressview;

/**
 * description:
 * user: chenzheng
 * date: 2017/1/21 0021
 * time: 17:17
 */
public class flowactivity extends appcompatactivity {

 private myprogressview mtasksview;

 @override
 protected void oncreate(@nullable bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  setcontentview(r.layout.activity_flow);

  initview();
 }

 private void initview() {
  mtasksview = (myprogressview) findviewbyid(r.id.flow_prgress_view);
 }

 public void beginanim(view view){
  mtasksview.setusedflow("200.0m");
  mtasksview.setmshowprogress(60);
 }
}

3.activity_flow.xml

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tc="http://schemas.android.com/apk/res-auto"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:padding="10dp"
 android:background="#fff"
 android:gravity="center_horizontal"
 android:orientation="vertical">

 <button
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:onclick="beginanim"
  android:text="开始动画"/>

 <com.czhappy.effectdemo.view.myprogressview
  android:id="@+id/flow_prgress_view"
  android:layout_width="100dp"
  android:layout_height="100dp"
  tc:circlecolor="@color/circle_color"
  tc:radius="44dp"
  tc:ringcolor="@color/ring_color"
  tc:strokewidth="6dp"
  android:layout_margintop="10dp"/>

</linearlayout>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

上一篇:

下一篇: