SwitchImageView.java 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package xn.hxp.weidith;
  2. import android.content.Context;
  3. import android.content.res.TypedArray;
  4. import android.os.Handler;
  5. import android.util.AttributeSet;
  6. import android.view.animation.AlphaAnimation;
  7. import android.view.animation.Animation;
  8. import androidx.appcompat.widget.AppCompatImageView;
  9. import xn.hxp.R;
  10. public class SwitchImageView extends AppCompatImageView {
  11. private static final long DURATION = 120_000; // 120秒
  12. private int defaultSrc;
  13. private int switchedSrc;
  14. private final Handler handler = new Handler();
  15. private Runnable restoreTask;
  16. private boolean isSwitched = false;
  17. public SwitchImageView(Context context) {
  18. super(context);
  19. init(context, null);
  20. }
  21. public SwitchImageView(Context context, AttributeSet attrs) {
  22. super(context, attrs);
  23. init(context, attrs);
  24. }
  25. public SwitchImageView(Context context, AttributeSet attrs, int defStyleAttr) {
  26. super(context, attrs, defStyleAttr);
  27. init(context, attrs);
  28. }
  29. private void init(Context context, AttributeSet attrs) {
  30. // 读取自定义属性
  31. TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SwitchImageView);
  32. defaultSrc = ta.getResourceId(R.styleable.SwitchImageView_defaultSrc, 0);
  33. switchedSrc = ta.getResourceId(R.styleable.SwitchImageView_switchedSrc, 0);
  34. ta.recycle();
  35. setImageResource(defaultSrc);
  36. setupClickListener();
  37. }
  38. private void setupClickListener() {
  39. setOnClickListener(v -> switchImageWithAnimation());
  40. }
  41. private void switchImageWithAnimation() {
  42. if (isSwitched) return; // 防止重复点击
  43. // 淡出动画
  44. AlphaAnimation fadeOut = new AlphaAnimation(1, 0);
  45. fadeOut.setDuration(300);
  46. fadeOut.setAnimationListener(new Animation.AnimationListener() {
  47. @Override
  48. public void onAnimationStart(Animation animation) {}
  49. @Override
  50. public void onAnimationEnd(Animation animation) {
  51. setImageResource(switchedSrc);
  52. // 淡入动画
  53. AlphaAnimation fadeIn = new AlphaAnimation(0, 1);
  54. fadeIn.setDuration(300);
  55. startAnimation(fadeIn);
  56. scheduleRestore();
  57. isSwitched = true;
  58. }
  59. @Override
  60. public void onAnimationRepeat(Animation animation) {}
  61. });
  62. startAnimation(fadeOut);
  63. }
  64. private void scheduleRestore() {
  65. // 取消之前的任务(如果有)
  66. if (restoreTask != null) {
  67. handler.removeCallbacks(restoreTask);
  68. }
  69. restoreTask = () -> {
  70. AlphaAnimation fadeOut = new AlphaAnimation(1, 0);
  71. fadeOut.setDuration(300);
  72. fadeOut.setAnimationListener(new Animation.AnimationListener() {
  73. @Override
  74. public void onAnimationStart(Animation animation) {}
  75. @Override
  76. public void onAnimationEnd(Animation animation) {
  77. setImageResource(defaultSrc);
  78. AlphaAnimation fadeIn = new AlphaAnimation(0, 1);
  79. fadeIn.setDuration(300);
  80. startAnimation(fadeIn);
  81. isSwitched = false;
  82. }
  83. @Override
  84. public void onAnimationRepeat(Animation animation) {}
  85. });
  86. startAnimation(fadeOut);
  87. };
  88. handler.postDelayed(restoreTask, DURATION);
  89. }
  90. @Override
  91. protected void onDetachedFromWindow() {
  92. super.onDetachedFromWindow();
  93. // 移除回调防止内存泄漏
  94. if (restoreTask != null) {
  95. handler.removeCallbacks(restoreTask);
  96. }
  97. }
  98. // 可选:手动恢复方法
  99. public void restoreImmediately() {
  100. if (restoreTask != null) {
  101. handler.removeCallbacks(restoreTask);
  102. }
  103. setImageResource(defaultSrc);
  104. isSwitched = false;
  105. }
  106. }