前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android开发笔记(十四)圆弧进度动画CircleAnimation

Android开发笔记(十四)圆弧进度动画CircleAnimation

作者头像
aqi00
发布2019-01-18 10:32:20
1.2K0
发布2019-01-18 10:32:20
举报
文章被收录于专栏:老欧说安卓

一个好看的APP,都有不少精致的动画效果。熟练运用各种动画技术,可让我们的APP灼灼生辉。Android在技术上把动画分为了三类,分别是帧动画FrameAnimation、补间动画TweenAnimation、属性动画,其中补间动画又分做五种:深浅动画AlphaAnimation、平移动画TranslateAnimation、缩放动画ScaleAnimation、旋转动画RotateAnimation、组合动画AnimationSet。网上对这些动画的说明资料有不少,所以博主就不打算介绍它们的基本用法了,还是说说另外的一些常用动画。 首先介绍的是圆弧进度动画,像我们下载文件或者是做其他什么事情,都想知道当前到什么进度了。在Windows下常用来表达的是细长的进度条,但在手机上因为屏幕限制,我们更喜欢展示圆形或弧形的进度圈。所以接下来说的便是这个进度圆圈的动画,同时也正好与上一节自定义视图的绘制方法结合起来,复习复习加深巩固。 绘制圆弧动画,主要思路在一段指定的时间内,持续间隔地绘制一个扇形或圆弧,如同放电影的原理那样,每秒连续播放二三十张图片,连起来整个画面就动了。 其次还要进行一些参数的设置,如设置该圆圈的位置、开始和结束的角度,以及转动的速率等等,还有画笔的颜色、粗细、样式等等。 另外为了区分处理背景和动画,我们还要处理背景视图(用于衬托动画)、前景视图(用于展示动画)。 剩下的就是在绘制的时候做好每帧之间的延迟时间,重绘视图可用invalidate和postInvalidate方法,延迟可用Thread.sleep和Handler.postDelayed方法。 实现代码不难,直接贴出来了

代码语言:javascript
复制
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Paint.Style;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.RelativeLayout;

public class CicleAnimation extends RelativeLayout {
	private final static String TAG = "CicleAnimation";
	private RectF mRect = new RectF(10, 10, 160, 160);
	private int mBeginAngle = 0;
	private int mEndAngle = 270;
	private int mFrontColor = 0xff00ff00;
	private float mFrontLine = 5;
	private Style mFrontStyle = Style.STROKE;
	private int mShadeColor = 0xffeeeeee;
	private float mShadeLine = 5;
	private Style mShadeStyle = Style.STROKE;
	private ShadeView mShadeView;
	private FrontView mFrontView;
	private int mRate = 2;
	private int mDrawTimes;
	private int mInterval = 70;
	private int mFactor;
	private Context mContext;
	private int mSeq = 0;
	private int mDrawingAngle = 0;

	public CicleAnimation(Context context) {
		super(context);
		mContext = context;
	}
	
	public CicleAnimation render() {
		mShadeView = new ShadeView(mContext);
		this.addView(mShadeView);
		mFrontView = new FrontView(mContext);
		this.addView(mFrontView);
		refresh();
		return this;
	}

	public void refresh() {
		mSeq = 0;
        mDrawingAngle=0;
		mDrawTimes = mEndAngle/mRate;
		mFactor = mDrawTimes/mInterval + 1;
		Log.d(TAG, "mDrawTimes="+mDrawTimes+",mInterval="+mInterval+",mFactor="+mFactor);
		mFrontView.invalidateView();
	}

	public void setRect(int left, int top, int right, int bottom) {
		mRect = new RectF(left, top, right, bottom);
	}

	public void setAngle(int begin_angle, int end_angle) {
		mBeginAngle = begin_angle;
		mEndAngle = end_angle;
	}
	
	//speed:每次移动几个度数   frames:每秒移动几帧
	public void setmRate(int speed, int frames) {
		mRate = speed;
		mInterval = 1000/frames;
	}

	public void setFront(int color, float line, Style style) {
		mFrontColor = color;
		mFrontLine = line;
		mFrontStyle = style;
	}

	public void setShade(int color, float line, Style style) {
		mShadeColor = color;
		mShadeLine = line;
		mShadeStyle = style;
	}
	
	class ShadeView extends View {
		Paint paint;

		public ShadeView(Context context) {
			super(context);
			paint = new Paint();
			paint.setAntiAlias(true);
			paint.setDither(true);
			paint.setColor(mShadeColor);
			paint.setStrokeWidth(mShadeLine);
			paint.setStyle(mShadeStyle);
		}

		@Override
		protected void onDraw(Canvas canvas) {
			super.onDraw(canvas);
			canvas.drawArc(mRect, mBeginAngle, 360, false, paint);
		}
	}

	class FrontView extends View {
		Paint paint;

		public FrontView(Context context) {
			super(context);
			paint = new Paint();
			paint.setAntiAlias(true);         //设置画笔为无锯齿
			paint.setDither(true);            //防抖动
			paint.setColor(mFrontColor);       //设置画笔颜色
			paint.setStrokeWidth(mFrontLine);  //线宽
			paint.setStyle(mFrontStyle);       //画笔类型 STROKE空心 FILL 实心
			//paint.setStrokeJoin(Paint.Join.ROUND); //画笔接洽点类型 如影响矩形直角的外轮廓
			paint.setStrokeCap(Paint.Cap.ROUND);  ////画笔笔刷类型 如影响画笔的始末端
		}

		@Override
		protected void onDraw(Canvas canvas) {
			super.onDraw(canvas);
			canvas.drawArc(mRect, mBeginAngle, (float) (mDrawingAngle), false, paint);
		}

	    public void invalidateView(){
	        handler.postDelayed(drawRunnable, 0);
	    }

	    private Handler handler = new Handler();

	    Runnable drawRunnable = new Runnable() {
	        @Override
	        public void run() {
	            if (mDrawingAngle >= mEndAngle) {
	            	mDrawingAngle = mEndAngle;
	                invalidate();
	                //移除当前Runnable
	                handler.removeCallbacks(drawRunnable);
	            } else {
	            	mDrawingAngle = mSeq*mRate;
	            	mSeq++;
	                handler.postDelayed(drawRunnable, (long) (mInterval-mSeq/mFactor));
	                invalidate();
	            }
	        }
	    };
	}

}

调用的代码如下

代码语言:javascript
复制
		Button btn_play = (Button) findViewById(R.id.btn_play);
		btn_play.setOnClickListener(this);
		LinearLayout ll_layout = (LinearLayout) findViewById(R.id.ll_layout);
		mCircle = new CicleAnimation(this);
		ll_layout.addView(mCircle);
		mCircle.render();

下面是圆弧动画的效果图

点击下载本文用到的圆弧进度动画代码

点此查看Android开发笔记的完整目录

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015年12月10日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档