materialDesign过度动画
来源:互联网 发布:openresty nginx 编辑:程序博客网 时间:2024/05/18 03:55
怎么样,很炫吧
github地址
定义个接口
public interface LoadState { void drawState(Canvas canvas);}
自定义view实现加载动画
/** * Created by marc on 2017/6/28. */public class LoadView extends View { /** * 大圆的半径(里面含有好多小圆) */ private float mRotationRadius = 90; /** * 小圆的半径 */ private float mCircleRadius = 18; /** * 小圆的颜色列表 */ private int[] mCircleColors; /** * 小圆旋转一周需要的时间 */ private long mRotationDuration = 1200; /** * 其他动画执行的时间(除了旋转的动画) */ private long mSplashDuration = 500; /** * view的背景颜色 */ private int mBgColor = Color.WHITE; /** * 当前大圆的半径(动态变化) */ private float mCurrentRatationRadios; /** * 当前大圆旋转的角度(弧度) */ private float mCurrentRotationAngle = 0f; /** * 空心圆半径 */ private float mHoleRadius = 0f; /** * 绘制圆的画笔 */ private Paint mPaint = new Paint(); /** * 绘制背景的画笔 */ private Paint mBgPaint = new Paint(); /** * view中心的坐标 */ private float mCenterX; private float mCenterY; /** * view对角线的一半 */ private float mDiagonalDist; /** * 保存当前动画状态-->当前在执行那种动画 */ private LoadState mState = null; /** * 小圆之间的间隔角度 */ private float mRotationAngle = 0f; /** * 聚合后缩放圆的半径 */ private float mScaleCircle; public LoadView(Context context) { this(context, null); } public LoadView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public LoadView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } /** * 初始化 */ private void init(Context context) { //抗锯齿 mPaint.setAntiAlias(true); mBgPaint.setAntiAlias(true); //设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰 mPaint.setDither(true); mBgPaint.setDither(true); //设置画笔的样式:空心 mBgPaint.setStyle(Paint.Style.STROKE); //设置画笔颜色 mBgPaint.setColor(mBgColor); //旋转的时候大圆的半径不变,为初始化值 mCurrentRatationRadios = mRotationRadius; //聚合后放大圆的初始半径为小圆半径 mScaleCircle = mCircleRadius; //获取颜色数组,小圆的个数和定义颜色的个数相等 mCircleColors = context.getResources().getIntArray(R.array.circleColor); if (mCircleColors.length > 0) { //每个小圆之间的间隔角度(弧度) mRotationAngle = (float) (2 * Math.PI / mCircleColors.length); } } /** * 获取view的中点坐标,view对角线长度的一半 */ @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mCenterX = w / 2f; mCenterY = h / 2f; mDiagonalDist = (float) (Math.sqrt(w * w + h * h) / 2f); } @Override protected void onDraw(Canvas canvas) { //如果开始为空,则执行旋转动画 if (mState == null) { mState = new RotationState(); } //这边采用多态的方式,不断改变mState对象类型,执行不同的绘图动作 mState.drawState(canvas); super.onDraw(canvas); } /** * 数据加载完毕,关闭第一个动画,执行后面三个动画 */ public void splashAndDisappear() { //取消第一个动画 if (mState != null && mState instanceof RotationState) { ((RotationState) mState).cancel(); post(new Runnable() { @Override public void run() { mState = new MergingState(); } }); } } /** * 旋转动画 */ private class RotationState implements LoadState { private ValueAnimator animator; public RotationState() { animator = ValueAnimator.ofFloat(0f, (float) (2 * Math.PI)); animator.setDuration(mRotationDuration); //设置无限循环 animator.setRepeatCount(ValueAnimator.INFINITE); //匀速旋转 animator.setInterpolator(new LinearInterpolator()); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { //获取大圆旋转的当前角度 mCurrentRotationAngle = (float) animation.getAnimatedValue(); //重绘图像 invalidate(); } }); animator.start(); } @Override public void drawState(Canvas canvas) { clearCanvas(canvas); darwCircle(canvas); } /** * 取消旋转动画 */ public void cancel() { animator.cancel(); } } /** * 绘制小圆 * * @param canvas */ private void darwCircle(Canvas canvas) { for (int i = 0; i < mCircleColors.length; i++) { //设置画笔颜色 mPaint.setColor(mCircleColors[i]); //小圆的x坐标 float cx = (float) (mCurrentRatationRadios * Math.cos(mCurrentRotationAngle + mRotationAngle * i) + mCenterX); float cy = (float) (mCurrentRatationRadios * Math.sin(mCurrentRotationAngle + mRotationAngle * i) + mCenterY); canvas.drawCircle(cx, cy, mCircleRadius, mPaint); } } /** * 清空画布 * * @param canvas */ private void clearCanvas(Canvas canvas) { //如果空心圆的半径为0,则清空画布,如果mHoleRadius不为零,说明正在执行扩散动画 if (mHoleRadius > 0f) { //画笔的宽度 mBgPaint.setStrokeWidth(mDiagonalDist - mHoleRadius); //空心圆的半径 float radius = mDiagonalDist / 2 + mHoleRadius / 2; canvas.drawCircle(mCenterX, mCenterY, radius, mBgPaint); } else { canvas.drawColor(mBgColor); } } /** * 聚合动画 */ private class MergingState implements LoadState { private ValueAnimator animator; public MergingState() { animator = ValueAnimator.ofFloat(0f, mRotationRadius); //开始有个弹射效果,输入的参数越大,弹射效果越明显 animator.setInterpolator(new OvershootInterpolator(6f)); animator.setDuration(mSplashDuration); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mCurrentRatationRadios = (float) animation.getAnimatedValue(); invalidate(); } }); //反向计算 animator.reverse(); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); post(new Runnable() { @Override public void run() { mState = new CircleStae(); } }); } }); } @Override public void drawState(Canvas canvas) { clearCanvas(canvas); darwCircle(canvas); } } /** * 圆缩放动画 */ private class CircleStae implements LoadState { private ValueAnimator animator; public CircleStae() { animator = ValueAnimator.ofFloat(mCircleRadius, 2.5f * mCircleRadius, mCircleRadius); animator.setDuration(mSplashDuration); animator.setInterpolator(new LinearInterpolator()); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { //当前圆的圆心 mScaleCircle = (float) animation.getAnimatedValue(); //重绘图像 invalidate(); } }); animator.start(); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); post(new Runnable() { @Override public void run() { mState = new ExpandingStae(); } }); } }); } @Override public void drawState(Canvas canvas) { clearCanvas(canvas); canvas.drawCircle(mCenterX, mCenterY, mScaleCircle, mPaint); } } /** * 扩散动画 */ private class ExpandingStae implements LoadState { private ValueAnimator animator; public ExpandingStae() { animator = ValueAnimator.ofFloat(0, mDiagonalDist); animator.setDuration(mSplashDuration); //扩散我这边使用的是匀速,可以换成加速:AccelerateInterpolator animator.setInterpolator(new LinearInterpolator()); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { //获取空心圆的半径 mHoleRadius = (float) animation.getAnimatedValue(); //重绘图像 invalidate(); } }); animator.start(); } @Override public void drawState(Canvas canvas) { clearCanvas(canvas); } }}
activity中执行
public class MdLoadActivity extends AppCompatActivity { private LoadView loadView; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); SplashView splashView = new SplashView(MdLoadActivity.this); ContentView contentView = new ContentView(MdLoadActivity.this); loadView = new LoadView(this); FrameLayout fl = new FrameLayout(this);// fl.addView(splashView); fl.addView(contentView); fl.addView(loadView); setContentView(fl); handler.postDelayed(() -> loadView.splashAndDisappear(), 2000); } private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); } };
阅读全文
0 0
- materialDesign过度动画
- MaterialDesign动画
- Android MaterialDesign 转场动画
- (三十九)MaterialDesign 动画
- QML动画和过度
- cocos2d-x 过度动画
- setVisibility()设置过度动画
- QML动画与过度
- Activity过度动画应用
- QML动画和过度
- QML动画和过度
- MaterialDesign
- MaterialDesign
- MaterialDesign
- MaterialDesign
- MaterialDesign
- MaterialDesign
- MaterialDesign
- package control: install提示There Are No Packages Available For Installation
- https://stackoverflow.com/questions/37505484/cant-exit-git-commit-in-windows
- Mybatis Generator相关xml配置文件含义解析
- Ubuntu使用教程:E: 无法获得锁 /var/lib/apt/lists/lock
- Chapter 8 NP-complete problems课后习题8.16
- materialDesign过度动画
- Android Studio SDK 更新方法
- 初次使用PermissionsDispatcher碰到的问题
- 消除Qt运行边框
- eval和``及$()
- java-并发集合-阻塞队列 LinkedBlockingQueue 演示
- android 自定义属性
- Scala入门到精通——第七节:类和对象(二)
- Vue1.0学习总结(2)———交互(vue-resoucre的使用)