Android_loading动画1

package com.example.loadingviewdemo;

import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.animation.LinearInterpolator;

public class RotateLoading extends View {

	private int color;
	private int width;
	private int shadowPosition;
	private static final int DEFAULT_WIDTH = 6;// 默认宽度为6
	private static final int DEFAULT_SHADOW_POSITION = 2;

	private Paint mPaint;// 画笔
	private float arc;
	private RectF loadingRectF;
	private RectF shadowRectF;
	private boolean isStart = false;
	private int topDegree = 10;// 上面的角度
	private int bottomDegree = 190;// 下面的角度
	private boolean changeBigger = true;

	public RotateLoading(Context context) {
		super(context);
		initView(context, null);
	}

	public RotateLoading(Context context, AttributeSet attrs) {
		super(context, attrs);
		initView(context, attrs);
	}

	public RotateLoading(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		initView(context, attrs);
	}

	private void initView(Context context, AttributeSet attrs) {
		color = Color.WHITE;
		width = dpToPx(context, DEFAULT_WIDTH);
		shadowPosition = dpToPx(context, DEFAULT_SHADOW_POSITION);

		if (null != attrs) {
			TypedArray attr = context.obtainStyledAttributes(attrs,
					R.styleable.RotateLoading);
			color = attr.getColor(R.styleable.RotateLoading_loading_color,
					Color.WHITE);
			width = attr.getDimensionPixelSize(
					R.styleable.RotateLoading_loading_width,
					dpToPx(context, DEFAULT_WIDTH));
			shadowPosition = attr.getInt(
					R.styleable.RotateLoading_shadow_position,
					DEFAULT_SHADOW_POSITION);
			attr.recycle();
		}
		mPaint = new Paint();
		mPaint.setColor(color);// 设置颜色
		mPaint.setAntiAlias(true);// 设置抗锯齿
		mPaint.setStyle(Paint.Style.STROKE);// 样式是STROKE空心
		mPaint.setStrokeWidth(width);
		mPaint.setStrokeCap(Paint.Cap.ROUND);
	}

	/** 数据可以在onMeasure方法中初始化 */
	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		arc = 10;

		loadingRectF = new RectF(2 * width, 2 * width, w - 2 * width, h - 2
				* width);
		shadowRectF = new RectF(2 * width + shadowPosition, 2 * width
				+ shadowPosition, w - 2 * width + shadowPosition, h - 2 * width
				+ shadowPosition);

		Log.e("onSizeChanged", "----" + w + "----" + h + "----" + oldw + "----"
				+ oldh);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		Log.e("onDraw", "----");
		if (!isStart) {
			return; // 启动动画的时候,为true
		}

		// 绘制阴影
		mPaint.setColor(Color.parseColor("#1a000000"));
		canvas.drawArc(shadowRectF, topDegree, arc, false, mPaint);// 绘制矩形区域,开始角度,连续角度,不用中心点,画笔描边的
		canvas.drawArc(shadowRectF, bottomDegree, arc, false, mPaint);// 绘制另一半的弧

		// 绘制旋转的两个半弧
		mPaint.setColor(color);
		canvas.drawArc(loadingRectF, topDegree, arc, false, mPaint);
		canvas.drawArc(loadingRectF, bottomDegree, arc, false, mPaint);

		// 每次绘制一次都要整体旋转10度
		topDegree += 10;
		bottomDegree += 10;

		// 大于360度的时候就要重头开始
		if (topDegree > 360) {
			topDegree = topDegree - 360;
		}
		if (bottomDegree > 360) {
			bottomDegree = bottomDegree - 360;
		}
		if (changeBigger) {
			if (arc < 160) {
				arc += 2.5;
				invalidate();
			}
		} else {
			if (arc > 10) {
				arc -= 5;
				invalidate();
			}
		}
		if (arc == 160 || arc == 10) {
			changeBigger = !changeBigger;
			invalidate();
		}
	}

	/** dp转化为px */
	private int dpToPx(Context context, int dpValue) {
		int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
				dpValue, context.getResources().getDisplayMetrics());
		return px;
	}

	public void start() {
		startAnimator();
		isStart = true;
		invalidate();
	}

	public void stop() {
		stopAnimator();
		invalidate();
	}

	@SuppressLint("NewApi")
	private void startAnimator() {
		ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(this, "scaleX",
				0.0f, 1);
		ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(this, "scaleY",
				0.0f, 1);
		scaleXAnimator.setDuration(300);
		scaleXAnimator.setInterpolator(new LinearInterpolator());
		scaleYAnimator.setDuration(300);
		scaleXAnimator.setInterpolator(new LinearInterpolator());
		AnimatorSet animationSet = new AnimatorSet();
		animationSet.playTogether(scaleXAnimator, scaleYAnimator);// 组合动画一起执行
		animationSet.start();

	}

	@SuppressLint("NewApi")
	private void stopAnimator() {
		ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(this, "scaleX",
				1, 0);
		ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(this, "scaleY",
				1, 0);
		scaleXAnimator.setDuration(300);
		scaleXAnimator.setInterpolator(new LinearInterpolator());
		scaleYAnimator.setDuration(300);
		scaleYAnimator.setInterpolator(new LinearInterpolator());
		AnimatorSet animatorSet = new AnimatorSet();
		animatorSet.playTogether(scaleXAnimator, scaleYAnimator);
		animatorSet.addListener(new AnimatorListener() {

			@Override
			public void onAnimationStart(Animator arg0) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onAnimationRepeat(Animator arg0) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onAnimationEnd(Animator arg0) {
				// TODO Auto-generated method stub
				isStart = false;
			}

			@Override
			public void onAnimationCancel(Animator arg0) {
				// TODO Auto-generated method stub

			}
		});
		animatorSet.start();
	}

	public boolean isStart() {
		return isStart;
	}
}

invalidate方法会在将来某个时间段会使这个View失效,再次重新绘制,会再次调用onDraw方法,在主线程中绘制图形,这就达到了一直绘制的效果,但是也可以封装一个Runnable类,调用view的post方法,可以达到类似的效果



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值