EnterAnimLayout.java 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package com.bestv.edu.view;
  2. import android.content.Context;
  3. import android.content.res.TypedArray;
  4. import android.graphics.Canvas;
  5. import android.util.AttributeSet;
  6. import android.view.MotionEvent;
  7. import android.widget.FrameLayout;
  8. import com.bestv.edu.R;
  9. import com.bestv.edu.anim.Anim;
  10. /**
  11. * author : 程中强
  12. * e-mail : 740479946@qq.com
  13. * date : 2022/8/916:40
  14. * desc :
  15. * version: 1.0
  16. */
  17. public class EnterAnimLayout extends FrameLayout {
  18. private Anim anim ; //需要播放的动画类型
  19. private long startTime = 0;//开始时间
  20. private boolean mIsAnimaionRun = false;//开始播放动画的标志位,设置为true,然后invalidate即开始播放动画
  21. private boolean mIsVisibleAtFirst = true;//view所在页面打开时是否显示此view
  22. public EnterAnimLayout(Context context) {
  23. super(context);
  24. initialize();
  25. }
  26. public EnterAnimLayout(Context context, AttributeSet attrs) {
  27. super(context, attrs);
  28. TypedArray attribute = context.obtainStyledAttributes(attrs, R.styleable.EnterAnimLayout);
  29. mIsVisibleAtFirst = attribute.getBoolean(R.styleable.EnterAnimLayout_isVisibleAtFirst, true);
  30. attribute.recycle();
  31. initialize();
  32. }
  33. public EnterAnimLayout(Context context, AttributeSet attrs, int defStyleAttr) {
  34. super(context, attrs, defStyleAttr);
  35. TypedArray attribute = context.obtainStyledAttributes(attrs, R.styleable.EnterAnimLayout);
  36. mIsVisibleAtFirst = attribute.getBoolean(R.styleable.EnterAnimLayout_isVisibleAtFirst, false);
  37. attribute.recycle();
  38. initialize();
  39. }
  40. protected void initialize() {
  41. }
  42. public void setAnim(Anim anim) {
  43. this.anim = anim;
  44. }
  45. public long getStartTime() {
  46. return startTime;
  47. }
  48. public void setStartTime(long startTime) {
  49. this.startTime = startTime;
  50. }
  51. public boolean ismIsAnimaionRun() {
  52. return mIsAnimaionRun;
  53. }
  54. public void setmIsAnimaionRun(boolean mIsAnimaionRun) {
  55. this.mIsAnimaionRun = mIsAnimaionRun;
  56. }
  57. @Override
  58. protected void dispatchDraw(Canvas canvas) {
  59. //如果设置了打开页面时正常显示,并且未设置播放动画,则正常分发draw
  60. if (mIsVisibleAtFirst && !mIsAnimaionRun) {
  61. super.dispatchDraw(canvas);
  62. return;
  63. }
  64. //如果设置了打开页面时控件先不可见,并且未设置播放动画,则不分发draw
  65. if (!mIsVisibleAtFirst && !mIsAnimaionRun) {
  66. return;
  67. }
  68. //mIsAnimaionRun 为true,播放动画,自定义分发draw
  69. //计算动画已播放时间比率rate=(当前时间-动画开始时间)/总共需要播放的时间
  70. long currentTime = System.currentTimeMillis();
  71. float rate = ((float)(currentTime - startTime) )/ anim.totalPaintTime;
  72. rate = rate > 1 ? 1 : rate;
  73. //先交给anim根据当前动画已播放时间比率来处理canvas,把处理后的canvas再分发给子view来draw
  74. //不同的anim会有不同的处理canvas的方式
  75. anim.handleCanvas(canvas,rate);
  76. super.dispatchDraw(canvas);
  77. //如果动画未播放完成,则继续刷新,如果已完成,则不继续刷新,重置标志位。
  78. if (rate < 1) {
  79. invalidate();
  80. } else {
  81. mIsAnimaionRun = false;
  82. mIsVisibleAtFirst = true;
  83. }
  84. }
  85. @Override
  86. public boolean onInterceptTouchEvent(MotionEvent ev) {
  87. //正在播放动画时点击才拦截
  88. if (ev.getAction() == MotionEvent.ACTION_DOWN && mIsAnimaionRun == true) {
  89. mIsAnimaionRun = false;
  90. return true;
  91. }
  92. return super.onInterceptTouchEvent(ev);
  93. }
  94. }