LoadingComponent.java 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. package com.fujica.abk.utils;
  2. import com.fujica.abk.ResourceTable;
  3. import ohos.agp.animation.Animator;
  4. import ohos.agp.animation.AnimatorProperty;
  5. import ohos.agp.components.AttrSet;
  6. import ohos.agp.components.Component;
  7. import ohos.agp.components.ComponentContainer;
  8. import ohos.agp.components.DirectionalLayout;
  9. import ohos.agp.components.Image;
  10. import ohos.agp.components.LayoutScatter;
  11. import ohos.agp.components.ProgressBar;
  12. import ohos.agp.utils.Color;
  13. import ohos.agp.utils.LayoutAlignment;
  14. import ohos.app.Context;
  15. import ohos.eventhandler.EventHandler;
  16. import ohos.eventhandler.EventRunner;
  17. /**
  18. * Loading组件类,继承DirectionalLayout
  19. * 全屏遮罩,中间显示loading,不可点击,不可取消
  20. * 使用方式:在 AbilitySlice 中定义为属性,初始化后添加到根布局
  21. */
  22. public class LoadingComponent extends DirectionalLayout {
  23. private Component contentLayout;
  24. private Image loadingImage;
  25. private AnimatorProperty rotationAnimator;
  26. /**
  27. * 构造函数(用于代码创建)
  28. */
  29. public LoadingComponent(Context context) {
  30. super(context);
  31. initComponent(context);
  32. }
  33. /**
  34. * 构造函数(用于XML布局文件)
  35. */
  36. public LoadingComponent(Context context, AttrSet attrSet) {
  37. super(context, attrSet);
  38. initComponent(context);
  39. }
  40. /**
  41. * 构造函数(用于XML布局文件,带样式)
  42. */
  43. public LoadingComponent(Context context, AttrSet attrSet, String styleName) {
  44. super(context, attrSet, styleName);
  45. initComponent(context);
  46. }
  47. private void initComponent(Context context) {
  48. // 设置全屏布局属性
  49. setWidth(ComponentContainer.LayoutConfig.MATCH_PARENT);
  50. setHeight(ComponentContainer.LayoutConfig.MATCH_PARENT);
  51. setAlignment(LayoutAlignment.CENTER);
  52. setOrientation(VERTICAL);
  53. // 使用布局文件加载内容
  54. contentLayout = LayoutScatter.getInstance(context)
  55. .parse(ResourceTable.Layout_layout_loading_dialog, null, false);
  56. // 将内容布局添加到根布局中
  57. addComponent(contentLayout);
  58. // 获取图片组件
  59. Component imageComponent = contentLayout.findComponentById(ResourceTable.Id_loading_image);
  60. if (imageComponent instanceof Image) {
  61. loadingImage = (Image) imageComponent;
  62. // 创建旋转动画
  63. initRotationAnimation();
  64. }
  65. // 默认隐藏
  66. setVisibility(HIDE);
  67. }
  68. /**
  69. * 初始化旋转动画
  70. */
  71. private void initRotationAnimation() {
  72. if (loadingImage == null) {
  73. return;
  74. }
  75. // 先设置初始旋转角度为0
  76. loadingImage.setRotation(0f);
  77. // 创建旋转动画属性
  78. rotationAnimator = loadingImage.createAnimatorProperty();
  79. // 设置旋转动画(从当前位置旋转360度)
  80. rotationAnimator.rotate(360f);
  81. // 设置动画持续时间(2秒)
  82. rotationAnimator.setDuration(2000);
  83. // 不设置无限循环,而是通过监听器手动控制
  84. rotationAnimator.setLoopedCount(1);
  85. // 设置动画曲线为线性(匀速旋转)
  86. rotationAnimator.setCurveType(Animator.CurveType.LINEAR);
  87. // 添加动画状态监听器,在每次动画结束后重新启动
  88. rotationAnimator.setStateChangedListener(new Animator.StateChangedListener() {
  89. @Override
  90. public void onStart(Animator animator) {
  91. }
  92. @Override
  93. public void onStop(Animator animator) {
  94. }
  95. @Override
  96. public void onCancel(Animator animator) {
  97. }
  98. @Override
  99. public void onEnd(Animator animator) {
  100. // 每次动画结束时重置旋转角度为0,然后重新启动
  101. if (loadingImage != null && rotationAnimator != null && getVisibility() == VISIBLE) {
  102. loadingImage.setRotation(0f);
  103. // 延迟一小段时间后重新启动动画,实现连续旋转
  104. EventHandler mainHandler = new EventHandler(EventRunner.getMainEventRunner());
  105. mainHandler.postTask(() -> {
  106. if (rotationAnimator != null && loadingImage != null && getVisibility() == VISIBLE) {
  107. rotationAnimator.start();
  108. }
  109. }, 10);
  110. }
  111. }
  112. @Override
  113. public void onPause(Animator animator) {
  114. }
  115. @Override
  116. public void onResume(Animator animator) {
  117. }
  118. });
  119. }
  120. /**
  121. * 显示Loading
  122. */
  123. public void show() {
  124. setVisibility(VISIBLE);
  125. // 延迟启动旋转动画,确保组件已完全渲染
  126. EventHandler mainHandler = new EventHandler(EventRunner.getMainEventRunner());
  127. mainHandler.postTask(() -> {
  128. if (rotationAnimator != null && loadingImage != null) {
  129. // 重置旋转角度
  130. loadingImage.setRotation(0f);
  131. // 如果动画正在运行,先停止
  132. if (rotationAnimator.isRunning()) {
  133. rotationAnimator.stop();
  134. }
  135. // 启动动画
  136. rotationAnimator.start();
  137. }
  138. }, 100);
  139. }
  140. /**
  141. * 隐藏Loading
  142. */
  143. public void hide() {
  144. setVisibility(HIDE);
  145. // 停止旋转动画
  146. if (rotationAnimator != null && rotationAnimator.isRunning()) {
  147. rotationAnimator.stop();
  148. }
  149. }
  150. /**
  151. * 是否正在显示
  152. */
  153. public boolean isShowing() {
  154. return getVisibility() == VISIBLE;
  155. }
  156. }