@quicktvui/ai 1.0.7 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/package.json +1 -1
  2. package/rules/.clinerules +27 -4
  3. package/rules/.cursorrules +27 -4
  4. package/rules/.github/copilot-instructions.md +27 -4
  5. package/rules/.source/hippy/extend_views/CoverFlowHorizontalView.java +203 -0
  6. package/rules/.source/hippy/extend_views/CoverFlowVerticalView.java +203 -0
  7. package/rules/.source/hippy/extend_views/CoverFlowViewController.java +195 -0
  8. package/rules/.source/hippy/extend_views/EngineRootView.java +125 -0
  9. package/rules/.source/hippy/extend_views/ExtendTag.java +83 -0
  10. package/rules/.source/hippy/extend_views/FocusSearchHelper.java +124 -0
  11. package/rules/.source/hippy/extend_views/IRecyclerItemView.java +12 -0
  12. package/rules/.source/hippy/extend_views/JSEventHandleView.java +5 -0
  13. package/rules/.source/hippy/extend_views/MarqueeRelayManager.java +133 -0
  14. package/rules/.source/hippy/extend_views/MarqueeRelayTextView.java +211 -0
  15. package/rules/.source/hippy/extend_views/ProgressBarView.java +83 -0
  16. package/rules/.source/hippy/extend_views/ProgressBarViewController.java +145 -0
  17. package/rules/.source/hippy/extend_views/SeekBarView.java +104 -0
  18. package/rules/.source/hippy/extend_views/SeekBarViewController.java +218 -0
  19. package/rules/.source/hippy/extend_views/StateImageView.java +149 -0
  20. package/rules/.source/hippy/extend_views/StateImageViewController.java +34 -0
  21. package/rules/.source/hippy/extend_views/TVButtonView.java +314 -0
  22. package/rules/.source/hippy/extend_views/TVButtonViewController.java +89 -0
  23. package/rules/.source/hippy/extend_views/TVTextView.java +684 -0
  24. package/rules/.source/hippy/extend_views/TVViewActor.java +811 -0
  25. package/rules/.source/hippy/extend_views/TVViewActorHost.java +6 -0
  26. package/rules/.source/hippy/extend_views/TVViewActor/346/216/245/345/205/245.md +66 -0
  27. package/rules/.source/hippy/extend_views/TemplateUtil.java +336 -0
  28. package/rules/.source/hippy/extend_views/TextButtonNode.java +47 -0
  29. package/rules/.source/hippy/extend_views/TextViewController.java +377 -0
  30. package/rules/.source/hippy/extend_views/fastlist/CenterFlyInAnimator.java +96 -0
  31. package/rules/.source/hippy/extend_views/fastlist/ChildOnScreenScroller.java +548 -0
  32. package/rules/.source/hippy/extend_views/fastlist/ClonedViewTag.java +17 -0
  33. package/rules/.source/hippy/extend_views/fastlist/EventDeliverer.java +55 -0
  34. package/rules/.source/hippy/extend_views/fastlist/FastAdapter.java +4683 -0
  35. package/rules/.source/hippy/extend_views/fastlist/FastAdapterUtil.java +982 -0
  36. package/rules/.source/hippy/extend_views/fastlist/FastFlexNode.java +48 -0
  37. package/rules/.source/hippy/extend_views/fastlist/FastFlexView.java +873 -0
  38. package/rules/.source/hippy/extend_views/fastlist/FastFlexViewController.java +130 -0
  39. package/rules/.source/hippy/extend_views/fastlist/FastItemNode.java +67 -0
  40. package/rules/.source/hippy/extend_views/fastlist/FastItemView.java +306 -0
  41. package/rules/.source/hippy/extend_views/fastlist/FastItemViewController.java +106 -0
  42. package/rules/.source/hippy/extend_views/fastlist/FastListModule.java +95 -0
  43. package/rules/.source/hippy/extend_views/fastlist/FastListNode.java +90 -0
  44. package/rules/.source/hippy/extend_views/fastlist/FastListView.java +2466 -0
  45. package/rules/.source/hippy/extend_views/fastlist/FastListViewController.java +1038 -0
  46. package/rules/.source/hippy/extend_views/fastlist/FastListView/346/270/262/346/237/223/346/265/201/347/250/213/345/233/276.graffle +0 -0
  47. package/rules/.source/hippy/extend_views/fastlist/FastPendingView.java +47 -0
  48. package/rules/.source/hippy/extend_views/fastlist/ItemDecorations.java +71 -0
  49. package/rules/.source/hippy/extend_views/fastlist/ItemStoreNode.java +64 -0
  50. package/rules/.source/hippy/extend_views/fastlist/ItemStoreView.java +13 -0
  51. package/rules/.source/hippy/extend_views/fastlist/ItemStoreViewController.java +45 -0
  52. package/rules/.source/hippy/extend_views/fastlist/ListItemHolder.java +7 -0
  53. package/rules/.source/hippy/extend_views/fastlist/ListViewControlProp.java +41 -0
  54. package/rules/.source/hippy/extend_views/fastlist/MouseRecycleView.java +509 -0
  55. package/rules/.source/hippy/extend_views/fastlist/OnFastItemClickListener.java +12 -0
  56. package/rules/.source/hippy/extend_views/fastlist/OnFastItemFocusChangeListener.java +9 -0
  57. package/rules/.source/hippy/extend_views/fastlist/OnFastScrollStateChangedListener.java +7 -0
  58. package/rules/.source/hippy/extend_views/fastlist/PendingListNode.java +18 -0
  59. package/rules/.source/hippy/extend_views/fastlist/PendingViewController.java +13 -0
  60. package/rules/.source/hippy/extend_views/fastlist/PostHandlerView.java +6 -0
  61. package/rules/.source/hippy/extend_views/fastlist/PostTaskHolder.java +20 -0
  62. package/rules/.source/hippy/extend_views/fastlist/ReplaceChildController.java +105 -0
  63. package/rules/.source/hippy/extend_views/fastlist/ReplaceChildView.java +312 -0
  64. package/rules/.source/hippy/extend_views/fastlist/TVListView.java +3692 -0
  65. package/rules/.source/hippy/extend_views/fastlist/TemplateCodeParser.java +247 -0
  66. package/rules/.source/hippy/extend_views/fastlist/Utils.java +572 -0
  67. package/rules/.source/hippy/extend_views/fastlist/ViewTag.java +317 -0
  68. package/rules/.source/hippy/extend_views/fastlist/VirtualListView.java +8 -0
  69. package/rules/.source/hippy/extend_views/fastlist/diff/FastListDataBindingHelper.java +320 -0
  70. package/rules/.source/hippy/extend_views/fastlist/diff/KeyDiffHelper.java +289 -0
  71. package/rules/.source/hippy/extend_views/fastlist/diff/NoKeyDiffHelper.java +278 -0
  72. package/rules/.source/hippy/extend_views/tag/FontTag.java +53 -0
  73. package/rules/.source/hippy/extend_views/tag/HtmlTag.java +191 -0
  74. package/rules/.source/hippy/extend_views/tag/HtmlTagHandler.java +185 -0
  75. package/rules/.source/hippy/extend_views/tag/SpanTag.java +160 -0
  76. package/rules/.source/hippy/extend_views/tag/TextFontSpan.java +102 -0
  77. package/rules/.source/hippy/extend_views/waterfall/Chunk.java +10 -0
  78. package/rules/.source/hippy/extend_views/waterfall/ChunkGroup.java +5 -0
  79. package/rules/.source/hippy/extend_views/waterfall/Section.java +4 -0
  80. package/rules/.source/hippy/extend_views/waterfall/Tabs.java +5 -0
  81. package/rules/.source/hippy/extend_views/waterfall/WaterfallUtils.java +26 -0
  82. package/rules/.source/hippy/hippy_uimanager/ControllerHolder.java +30 -0
  83. package/rules/.source/hippy/hippy_uimanager/ControllerManager.java +651 -0
  84. package/rules/.source/hippy/hippy_uimanager/ControllerRegistry.java +102 -0
  85. package/rules/.source/hippy/hippy_uimanager/ControllerUpdateManger.java +252 -0
  86. package/rules/.source/hippy/hippy_uimanager/CustomControllerHelper.java +425 -0
  87. package/rules/.source/hippy/hippy_uimanager/DiffUtils.java +526 -0
  88. package/rules/.source/hippy/hippy_uimanager/ExtendViewGroup.java +36 -0
  89. package/rules/.source/hippy/hippy_uimanager/HippyCustomViewCreator.java +29 -0
  90. package/rules/.source/hippy/hippy_uimanager/HippyGroupController.java +83 -0
  91. package/rules/.source/hippy/hippy_uimanager/HippyViewBase.java +27 -0
  92. package/rules/.source/hippy/hippy_uimanager/HippyViewController.java +2189 -0
  93. package/rules/.source/hippy/hippy_uimanager/HippyViewEvent.java +52 -0
  94. package/rules/.source/hippy/hippy_uimanager/IHippyZIndexViewGroup.java +24 -0
  95. package/rules/.source/hippy/hippy_uimanager/InternalExtendViewUtil.java +395 -0
  96. package/rules/.source/hippy/hippy_uimanager/ListItemRenderNode.java +143 -0
  97. package/rules/.source/hippy/hippy_uimanager/ListViewRenderNode.java +44 -0
  98. package/rules/.source/hippy/hippy_uimanager/MatrixUtil.java +470 -0
  99. package/rules/.source/hippy/hippy_uimanager/NativeGestureDispatcher.java +349 -0
  100. package/rules/.source/hippy/hippy_uimanager/NativeGestureProcessor.java +188 -0
  101. package/rules/.source/hippy/hippy_uimanager/PullFooterRenderNode.java +43 -0
  102. package/rules/.source/hippy/hippy_uimanager/PullHeaderRenderNode.java +43 -0
  103. package/rules/.source/hippy/hippy_uimanager/RenderManager.java +304 -0
  104. package/rules/.source/hippy/hippy_uimanager/RenderNode.java +533 -0
  105. package/rules/.source/hippy/hippy_uimanager/StateView.java +17 -0
  106. package/rules/.source/hippy/hippy_uimanager/TransformUtil.java +125 -0
  107. package/rules/.source/hippy/hippy_uimanager/ViewGroupDrawingOrderHelper.java +108 -0
  108. package/rules/.source/hippy/hippy_uimanager/ViewStateProvider.java +10 -0
  109. package/rules/.source/hippy/hippy_views/audioview/AudioPlayManager.java +457 -0
  110. package/rules/.source/hippy/hippy_views/audioview/AudioView.java +225 -0
  111. package/rules/.source/hippy/hippy_views/audioview/AudioViewController.java +135 -0
  112. package/rules/.source/hippy/hippy_views/common/CommonBackgroundDrawable.java +58 -0
  113. package/rules/.source/hippy/hippy_views/common/CommonBorder.java +37 -0
  114. package/rules/.source/hippy/hippy_views/custom/HippyCustomPropsController.java +61 -0
  115. package/rules/.source/hippy/hippy_views/hippylist/HippyRecyclerListAdapter.java +399 -0
  116. package/rules/.source/hippy/hippy_views/hippylist/HippyRecyclerView.java +378 -0
  117. package/rules/.source/hippy/hippy_views/hippylist/HippyRecyclerViewController.java +187 -0
  118. package/rules/.source/hippy/hippy_views/hippylist/HippyRecyclerViewHolder.java +39 -0
  119. package/rules/.source/hippy/hippy_views/hippylist/HippyRecyclerViewWrapper.java +134 -0
  120. package/rules/.source/hippy/hippy_views/hippylist/NodePositionHelper.java +55 -0
  121. package/rules/.source/hippy/hippy_views/hippylist/PreloadHelper.java +54 -0
  122. package/rules/.source/hippy/hippy_views/hippylist/PullFooterEventHelper.java +61 -0
  123. package/rules/.source/hippy/hippy_views/hippylist/PullHeaderEventHelper.java +127 -0
  124. package/rules/.source/hippy/hippy_views/hippylist/RecyclerViewEventHelper.java +394 -0
  125. package/rules/.source/hippy/hippy_views/image/HippyContentDrawable.java +113 -0
  126. package/rules/.source/hippy/hippy_views/image/HippyImageView.java +1608 -0
  127. package/rules/.source/hippy/hippy_views/image/HippyImageViewController.java +382 -0
  128. package/rules/.source/hippy/hippy_views/image/IImageStateListener.java +7 -0
  129. package/rules/.source/hippy/hippy_views/list/ChildOnScreenScroller.java +255 -0
  130. package/rules/.source/hippy/hippy_views/list/HippyListAdapter.java +647 -0
  131. package/rules/.source/hippy/hippy_views/list/HippyListItemView.java +162 -0
  132. package/rules/.source/hippy/hippy_views/list/HippyListItemViewController.java +45 -0
  133. package/rules/.source/hippy/hippy_views/list/HippyListView.java +915 -0
  134. package/rules/.source/hippy/hippy_views/list/HippyListViewController.java +622 -0
  135. package/rules/.source/hippy/hippy_views/list/HippyRecycler.java +31 -0
  136. package/rules/.source/hippy/hippy_views/list/IRecycleItemTypeChange.java +23 -0
  137. package/rules/.source/hippy/hippy_views/list/ItemDecorations.java +70 -0
  138. package/rules/.source/hippy/hippy_views/list/NegativeLongKeyFlinger.java +156 -0
  139. package/rules/.source/hippy/hippy_views/list/NodeHolder.java +34 -0
  140. package/rules/.source/hippy/hippy_views/list/RecycleViewFlinger.java +126 -0
  141. package/rules/.source/hippy/hippy_views/list/TVRecyclerView.java +2070 -0
  142. package/rules/.source/hippy/hippy_views/list/TVSingleLineListView.java +15 -0
  143. package/rules/.source/hippy/hippy_views/modal/HippyModalHostManager.java +102 -0
  144. package/rules/.source/hippy/hippy_views/modal/HippyModalHostView.java +597 -0
  145. package/rules/.source/hippy/hippy_views/modal/ModalHostHelper.java +46 -0
  146. package/rules/.source/hippy/hippy_views/modal/ModalStyleNode.java +34 -0
  147. package/rules/.source/hippy/hippy_views/modal/RequestCloseEvent.java +32 -0
  148. package/rules/.source/hippy/hippy_views/modal/ShowEvent.java +31 -0
  149. package/rules/.source/hippy/hippy_views/navigator/Navigator.java +126 -0
  150. package/rules/.source/hippy/hippy_views/navigator/NavigatorController.java +120 -0
  151. package/rules/.source/hippy/hippy_views/refresh/HippyPullFooterView.java +47 -0
  152. package/rules/.source/hippy/hippy_views/refresh/HippyPullFooterViewController.java +65 -0
  153. package/rules/.source/hippy/hippy_views/refresh/HippyPullHeaderView.java +39 -0
  154. package/rules/.source/hippy/hippy_views/refresh/HippyPullHeaderViewController.java +104 -0
  155. package/rules/.source/hippy/hippy_views/refresh/RefreshWrapper.java +237 -0
  156. package/rules/.source/hippy/hippy_views/refresh/RefreshWrapperController.java +62 -0
  157. package/rules/.source/hippy/hippy_views/refresh/RefreshWrapperItemController.java +39 -0
  158. package/rules/.source/hippy/hippy_views/refresh/RefreshWrapperItemView.java +26 -0
  159. package/rules/.source/hippy/hippy_views/scroll/HippyHorizontalScrollView.java +500 -0
  160. package/rules/.source/hippy/hippy_views/scroll/HippyOnScrollHelper.java +39 -0
  161. package/rules/.source/hippy/hippy_views/scroll/HippyScrollView.java +46 -0
  162. package/rules/.source/hippy/hippy_views/scroll/HippyScrollViewController.java +178 -0
  163. package/rules/.source/hippy/hippy_views/scroll/HippyScrollViewEventHelper.java +92 -0
  164. package/rules/.source/hippy/hippy_views/scroll/HippyVerticalScrollView.java +522 -0
  165. package/rules/.source/hippy/hippy_views/text/HippyTextView.java +512 -0
  166. package/rules/.source/hippy/hippy_views/text/HippyTextViewController.java +77 -0
  167. package/rules/.source/hippy/hippy_views/textinput/HippyTextInput.java +668 -0
  168. package/rules/.source/hippy/hippy_views/textinput/HippyTextInputController.java +528 -0
  169. package/rules/.source/hippy/hippy_views/textinput/TextInputNode.java +115 -0
  170. package/rules/.source/hippy/hippy_views/videoview/APEZProvider.java +287 -0
  171. package/rules/.source/hippy/hippy_views/videoview/APKExpansionSupport.java +82 -0
  172. package/rules/.source/hippy/hippy_views/videoview/PivotPoint.java +13 -0
  173. package/rules/.source/hippy/hippy_views/videoview/ScalableType.java +34 -0
  174. package/rules/.source/hippy/hippy_views/videoview/ScalableVideoView.java +265 -0
  175. package/rules/.source/hippy/hippy_views/videoview/ScaleManager.java +191 -0
  176. package/rules/.source/hippy/hippy_views/videoview/Size.java +19 -0
  177. package/rules/.source/hippy/hippy_views/videoview/VideoHippyView.java +917 -0
  178. package/rules/.source/hippy/hippy_views/videoview/VideoHippyViewController.java +236 -0
  179. package/rules/.source/hippy/hippy_views/videoview/ZipResourceFile.java +427 -0
  180. package/rules/.source/hippy/hippy_views/view/CardRootView.java +28 -0
  181. package/rules/.source/hippy/hippy_views/view/CustomLayoutView.java +10 -0
  182. package/rules/.source/hippy/hippy_views/view/CustomNodeView.java +5 -0
  183. package/rules/.source/hippy/hippy_views/view/DialogViewGroup.java +113 -0
  184. package/rules/.source/hippy/hippy_views/view/HippyViewGroup.java +2042 -0
  185. package/rules/.source/hippy/hippy_views/view/HippyViewGroupController.java +583 -0
  186. package/rules/.source/hippy/hippy_views/view/WindowRoot.java +5 -0
  187. package/rules/.source/hippy/hippy_views/viewpager/HippyViewPager.java +308 -0
  188. package/rules/.source/hippy/hippy_views/viewpager/HippyViewPagerAdapter.java +148 -0
  189. package/rules/.source/hippy/hippy_views/viewpager/HippyViewPagerController.java +246 -0
  190. package/rules/.source/hippy/hippy_views/viewpager/HippyViewPagerItem.java +27 -0
  191. package/rules/.source/hippy/hippy_views/viewpager/HippyViewPagerItemController.java +42 -0
  192. package/rules/.source/hippy/hippy_views/viewpager/ViewPagerPageChangeListener.java +114 -0
  193. package/rules/.source/hippy/hippy_views/viewpager/event/HippyPageItemExposureEvent.java +40 -0
  194. package/rules/.source/hippy/hippy_views/viewpager/event/HippyPageScrollEvent.java +43 -0
  195. package/rules/.source/hippy/hippy_views/viewpager/event/HippyPageScrollStateChangedEvent.java +42 -0
  196. package/rules/.source/hippy/hippy_views/viewpager/event/HippyPageSelectedEvent.java +42 -0
  197. package/rules/.source/hippy/hippy_views/webview/HippyWebView.java +160 -0
  198. package/rules/.source/hippy/hippy_views/webview/HippyWebViewBridge.java +20 -0
  199. package/rules/.source/hippy/hippy_views/webview/HippyWebViewController.java +103 -0
  200. package/rules/.source/hippy/hippy_views/webview/HippyWebViewInner.java +77 -0
  201. package/rules/.windsurfrules +27 -4
  202. package/rules/AGENTS.md +27 -4
  203. package/rules/CLAUDE.md +27 -3
  204. package/rules/GEMINI.md +25 -3
@@ -0,0 +1,1608 @@
1
+ /* Tencent is pleased to support the open source community by making Hippy available.
2
+ * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ package com.tencent.mtt.hippy.views.image;
17
+
18
+ import android.content.Context;
19
+ import android.graphics.Bitmap;
20
+ import android.graphics.Canvas;
21
+ import android.graphics.Color;
22
+ import android.graphics.Movie;
23
+ import android.graphics.Rect;
24
+ import android.graphics.drawable.Drawable;
25
+ import android.graphics.drawable.LayerDrawable;
26
+ import android.text.TextUtils;
27
+ import android.util.Log;
28
+ import android.view.MotionEvent;
29
+ import android.view.View;
30
+
31
+ import android.support.annotation.ColorInt;
32
+ import android.support.annotation.NonNull;
33
+ import android.support.annotation.Nullable;
34
+ import android.view.ViewGroup;
35
+
36
+ import com.tencent.extend.AttachInfo;
37
+ import com.tencent.extend.AutoFocusManager;
38
+ import com.tencent.extend.FocusManagerModule;
39
+ import com.tencent.extend.IFloatFocusManager;
40
+ import com.tencent.extend.ITVView;
41
+ import com.tencent.extend.TVFocusScaleExcuter;
42
+ import com.tencent.extend.views.ExtendTag;
43
+ import com.tencent.mtt.hippy.FocusDispatchView;
44
+ import com.tencent.mtt.hippy.HippyEngineContext;
45
+ import com.tencent.mtt.hippy.HippyInstanceContext;
46
+ import com.tencent.mtt.hippy.adapter.image.HippyDrawable;
47
+ import com.tencent.mtt.hippy.adapter.image.HippyImageLoader;
48
+ import com.tencent.mtt.hippy.common.HippyMap;
49
+ import com.tencent.mtt.hippy.dom.node.NodeProps;
50
+ import com.tencent.mtt.hippy.uimanager.ExtendViewGroup;
51
+ import com.tencent.mtt.hippy.uimanager.HippyViewBase;
52
+ import com.tencent.mtt.hippy.uimanager.HippyViewController;
53
+ import com.tencent.mtt.hippy.uimanager.HippyViewEvent;
54
+ import com.tencent.mtt.hippy.uimanager.NativeGestureDispatcher;
55
+ import com.tencent.mtt.hippy.uimanager.RenderNode;
56
+ import com.tencent.mtt.hippy.uimanager.StateView;
57
+ import com.tencent.mtt.hippy.uimanager.ViewStateProvider;
58
+ import com.tencent.mtt.hippy.utils.ExtendUtil;
59
+ import com.tencent.mtt.hippy.utils.LogUtils;
60
+ import com.tencent.mtt.hippy.utils.PixelUtil;
61
+ import com.tencent.mtt.hippy.utils.UrlUtils;
62
+ import com.tencent.mtt.hippy.views.common.CommonBackgroundDrawable;
63
+ import com.tencent.mtt.hippy.views.common.CommonBorder;
64
+ import com.tencent.extend.views.fastlist.ListItemHolder;
65
+ import com.tencent.extend.views.fastlist.PostHandlerView;
66
+ import com.tencent.extend.views.fastlist.PostTaskHolder;
67
+ import com.tencent.mtt.hippy.views.view.CustomLayoutView;
68
+ import com.tencent.mtt.supportui.adapters.image.IDrawableTarget;
69
+ import com.tencent.mtt.supportui.utils.struct.ArrayMap;
70
+ import com.tencent.mtt.supportui.views.asyncimage.AsyncImageView;
71
+ import com.tencent.mtt.supportui.views.asyncimage.BackgroundDrawable;
72
+ import com.tencent.mtt.supportui.views.asyncimage.ContentDrawable;
73
+
74
+ import java.util.Arrays;
75
+ import java.util.HashMap;
76
+ import java.util.Map;
77
+
78
+ @SuppressWarnings({"deprecation", "unused"})
79
+ public class HippyImageView extends AsyncImageView implements CommonBorder, HippyViewBase, ITVView, StateView,
80
+ PostTaskHolder, ListItemHolder, ViewStateProvider {
81
+
82
+ public static final String IMAGE_TYPE_APNG = "apng";
83
+ public static final String IMAGE_TYPE_GIF = "gif";
84
+ public static final String IMAGE_PROPS = "props";
85
+ public static final String IMAGE_VIEW_OBJ = "viewobj";
86
+
87
+
88
+ /** zhaopeng**/
89
+ private HippyMap initProps = new HippyMap();
90
+ private boolean mHasSetTempBackgroundColor = false;
91
+ private boolean mUserHasSetBackgroudnColor = false;
92
+ private int mUserSetBackgroundColor = Color.TRANSPARENT;
93
+
94
+ private boolean isAutoFocus = false;
95
+ private boolean isFillParent = false;
96
+ private boolean focusScaleOnDuplicateParentState = false;
97
+ //zhaopeng add roleType
98
+ private RoleType mRoleType = RoleType.UNDEFINE;
99
+
100
+ public enum RoleType {
101
+ UNDEFINE,
102
+ COVER,
103
+ ICON,
104
+ }
105
+
106
+
107
+
108
+ private IImageStateListener<HippyImageView> mCustomStateListener;
109
+
110
+ public void setCustomImageRequestListener(IImageStateListener mCustomImageRequestListener) {
111
+ this.mCustomStateListener = mCustomImageRequestListener;
112
+ }
113
+
114
+ public void setRoleType(RoleType mRoleType) {
115
+ this.mRoleType = mRoleType;
116
+ }
117
+
118
+ public RoleType getRoleType() {
119
+ return mRoleType;
120
+ }
121
+
122
+ public int getFetchState(){
123
+ return mUrlFetchState;
124
+ }
125
+
126
+ public void setFocusScaleOnDuplicateParentState(boolean focusScaleOnDuplicateParentState) {
127
+ this.focusScaleOnDuplicateParentState = focusScaleOnDuplicateParentState;
128
+ }
129
+
130
+
131
+ @Override
132
+ public void onSetSid(String sid) {
133
+ AutoFocusManager af = AutoFocusManager.findAutoFocusManagerFromRoot(this);
134
+ if(af != null){
135
+ if(af.isNextAutofocus(sid)){
136
+ //setAutoFocus(true,true);
137
+ onRequestAutofocus(this, this, ExtendViewGroup.AUTOFOCUS_TYPE_FORCE);
138
+ }
139
+ }
140
+
141
+ }
142
+
143
+ @Override
144
+ public boolean isAutoFocus() {
145
+ return isAutoFocus;
146
+ }
147
+
148
+ @Override
149
+ public void setAutoFocus(boolean b) {
150
+ setAutoFocus(b,false);
151
+ // if(b && isAttached() && !isFocused()
152
+ // && getWidth() > 0 && getHeight() > 0 && getVisibility() == View.VISIBLE){
153
+ // Log.i(AutoFocusManager.TAG,"auto requestFocus on setAutoFocus this:"+ExtendUtil.debugView(this));
154
+ // //AutoFocusManager.globalRequestFocus(this);
155
+ //// onRequestAutofocus(this,this,ExtendViewGroup.AUTOFOCUS_TYPE_FORCE);
156
+ // }
157
+ }
158
+
159
+ @Override
160
+ public void setAutoFocus(boolean b,boolean requestFocusOnExist) {
161
+ this.isAutoFocus = b;
162
+ if(b) {
163
+ Log.i(AutoFocusManager.TAG, "setAutoFocus true this:"+ExtendUtil.debugView(this)+",requestFocusOnExist "+requestFocusOnExist);
164
+ }
165
+ if(b && requestFocusOnExist && isAttached() && !isFocused()
166
+ && getWidth() > 0 && getHeight() > 0 && getVisibility() == View.VISIBLE) {
167
+ Log.i(AutoFocusManager.TAG, "auto requestFocus on setAutofocus this:" + ExtendUtil.debugView(this));
168
+ onRequestAutofocus(this, this, ExtendViewGroup.AUTOFOCUS_TYPE_FORCE);
169
+ }
170
+ }
171
+
172
+ private boolean skipRequestFocus = false;
173
+
174
+ @Override
175
+ public void setSkipRequestFocus(boolean b) {
176
+ this.skipRequestFocus = b;
177
+ }
178
+
179
+ @Override
180
+ public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
181
+ if(skipRequestFocus ||
182
+ (isInTouchMode() && !FocusManagerModule.getGlobalFocusConfig(getHippyContext()).enableFocusableTouchMode)){
183
+ Log.e(FocusDispatchView.TAG,"requestFocus return false on skipRequestFocus this:"+this);
184
+ return false;
185
+ }
186
+ boolean forceDisableFocus = FocusManagerModule.getGlobalFocusConfig(getHippyContext()).forceDisableFocus;
187
+ if(forceDisableFocus){
188
+ return false;
189
+ }
190
+ return super.requestFocus(direction, previouslyFocusedRect);
191
+ }
192
+
193
+ protected HippyEngineContext getHippyContext() {
194
+ return ((HippyInstanceContext) getContext()).getEngineContext();
195
+ }
196
+
197
+ //zhaopeng add
198
+ // private final BorderFrontDrawable focusFrontDrawable;
199
+
200
+ protected PostHandlerView mPostView;
201
+ private boolean onBindNew = false;
202
+ private boolean enablePostTask = false;
203
+ private boolean shouldBindReset = true;
204
+ //border相关配置本地变量
205
+ private boolean isBorderVisible;
206
+ private boolean isBlackRectEnable;
207
+ private int borderColor;
208
+ private float borderCorner;
209
+ private int borderWidth;
210
+ private int globalVisibility = View.VISIBLE;
211
+
212
+ public void setEnablePostTask(boolean enablePostTask) {
213
+ this.enablePostTask = enablePostTask;
214
+ }
215
+
216
+
217
+ @Override
218
+ public void setRootPostHandlerView(PostHandlerView pv) {
219
+ this.mPostView = pv;
220
+ }
221
+
222
+ private int getPostType() {
223
+ return hashCode();
224
+ }
225
+
226
+ // @Override
227
+ // protected void onWindowVisibilityChanged(int visibility) {
228
+ //
229
+ // }
230
+
231
+ @Override
232
+ public void onResetBeforeCache() {
233
+ if (isPostTaskEnabled()) {
234
+
235
+ mPostView.clearTask(POST_TASK_CATEGORY_IMG, getPostType());
236
+ }
237
+ if (LogUtils.isDebug()) {
238
+ Log.i("HippyImage", "onResetBeforeCache this:" + this);
239
+ }
240
+
241
+ if (mCustomStateList != null && !mCustomStateList.isEmpty()) {
242
+ //mCustomStateList.clear();
243
+ for(String key:mCustomStateList.keySet()){
244
+ setCustomState(key,false);
245
+ }
246
+ }
247
+ // setAutoFocus(false);
248
+ }
249
+
250
+ protected boolean isPostTaskEnabled() {
251
+ return enablePostTask && mPostView != null;
252
+ }
253
+
254
+ @Override
255
+ protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
256
+ super.onVisibilityChanged(changedView, visibility);
257
+ // if(LogUtils.isDebug()) {
258
+ // Log.i(AutoFocusManager.TAG,"div on view onVisibilityChanged visibility:"+visibility+",changedView:"+ExtendUtil.debugViewLite(changedView)+",hasFocus:"+changedView.hasFocus());
259
+ // if(changedView == getRootView()){
260
+ // Log.e(AutoFocusManager.TAG,"onVisibilityChanged on rootView visibility:"+visibility+",changedView:"+ExtendUtil.debugView(changedView));
261
+ // }
262
+ // }
263
+ // Log.v(AutoFocusManager.TAG,"onWindowVisibilityChanged visibility:"+visibility+",this:"+ExtendUtil.debugView(this));
264
+ globalVisibility = visibility;
265
+ if(AutoFocusManager.isAutofocusView(this) && visibility == View.VISIBLE){
266
+ if(changedView != getRootView()) {//这里如果是decorView,证明是activity之间的切换,理论上来说,不需要再次请求焦点
267
+ if (getWidth() > 0 && getHeight() > 0) {
268
+ if (LogUtils.isDebug()) {
269
+ Log.i(AutoFocusManager.TAG, "auto requestFocus on onWindowVisibilityChanged ,view:" + ExtendUtil.debugView(this));
270
+ }
271
+ onRequestAutofocus(this, this, ExtendViewGroup.AUTOFOCUS_TYPE_VISIBILITY);
272
+ } else {
273
+ Log.e(AutoFocusManager.TAG, "auto requestFocus return on onWindowVisibilityChanged ,view size invalid:" + ExtendUtil.debugView(this));
274
+ }
275
+ }else if(LogUtils.isDebug()){
276
+ Log.e(AutoFocusManager.TAG,"auto requestFocus return on rootView changed:"+ExtendUtil.debugView(changedView));
277
+ }
278
+ }
279
+ // if(visibility == View.VISIBLE) {
280
+ // if(getWidth() <1 || getHeight() < 1){
281
+ // Log.e(AutoFocusManager.TAG, "------onVisibilityChanged this:" + this + ",isAttached:" + isAttached() + ",width:" + getWidth());
282
+ // }else {
283
+ // Log.v(AutoFocusManager.TAG, "------onVisibilityChanged this:" + this + ",isAttached:" + isAttached() + ",width:" + getWidth());
284
+ // }
285
+ // }else{
286
+ // Log.e(AutoFocusManager.TAG, "------onVisibilityChanged to false this:" + this + ",isAttached:" + isAttached() + ",width:" + getWidth());
287
+ // }
288
+ // if(visibility == View.VISIBLE && (AutoFocusManager.isAutofocusView(this)) && getWidth() > 0 && getHeight() > 0){
289
+ // Log.i(AutoFocusManager.TAG,"auto requestFocus on onVisibilityChanged this:"+this);
290
+ // //AutoFocusManager.globalRequestFocus(this);
291
+ // onRequestAutofocus(this,this,ExtendViewGroup.AUTOFOCUS_TYPE_VISIBILITY);
292
+ // }
293
+ }
294
+
295
+ @Override
296
+ protected void postTask(Runnable task, int delayLoad) {
297
+ if (isPostTaskEnabled()) {
298
+ if (LogUtils.isDebug()) {
299
+ Log.i("HippyImage", "postTask by postView:" + hashCode() + ",url:" + getUrl() + ",task:" + task.hashCode() + ",mPostView:" + ((View) mPostView).getId());
300
+ }
301
+ mPostView.clearTask(POST_TASK_CATEGORY_IMG, getPostType());
302
+ mPostView.postTask(POST_TASK_CATEGORY_IMG, getPostType(), task, delayLoad);
303
+ } else {
304
+ if (LogUtils.isDebug()) {
305
+ Log.i("HippyImage", "postTask by super:" + this);
306
+ }
307
+ super.postTask(task, delayLoad);
308
+ }
309
+ }
310
+
311
+ /**
312
+ * 新增beforeItemBind方法,onItemBind前逻辑处理
313
+ *
314
+ * @param url bind的图片url
315
+ */
316
+ public void beforeItemBind(Object url) {
317
+ if (LogUtils.isDebug()) {
318
+ Log.e("HippyImage", "beforeItemBind:" + hashCode() + ",url:" + url);
319
+ }
320
+ shouldBindReset = !(url instanceof String) || !TextUtils.equals(getUrl(), (String) url);
321
+ //setAutoFocus(false);
322
+ }
323
+
324
+
325
+
326
+ @Override
327
+ public void onItemBind() {
328
+ if (LogUtils.isDebug()) {
329
+ Log.e("HippyImage", "onItemBind:" + hashCode() + ",url:" + getUrl());
330
+ }
331
+ if (isPostTaskEnabled() && shouldBindReset) {
332
+ //resetContent();
333
+ // mOldDrawable = getBackground();
334
+ if (mBGDrawable != null) {
335
+ setBackgroundDrawable(mBGDrawable);
336
+ } else {
337
+ setBackgroundDrawable(null);
338
+ }
339
+ invalidate();
340
+ onBindNew = true;
341
+ mPostView.clearTask(POST_TASK_CATEGORY_IMG, getPostType());
342
+ }
343
+ shouldBindReset = true;
344
+ }
345
+
346
+ //zhaopeng
347
+
348
+ /**
349
+ * 播放GIF动画的关键类
350
+ */
351
+ private Movie mGifMovie;
352
+ private int mGifStartX = 0;
353
+ private int mGifStartY = 0;
354
+ private float mGifScaleX = 1;
355
+ private float mGifScaleY = 1;
356
+ private boolean mGifMatrixComputed = false;
357
+ private int mGifProgress = 0;
358
+ private long mGifLastPlayTime = -1;
359
+ private boolean selectState = false;
360
+
361
+ @Override
362
+ public void resetProps() {
363
+ HippyViewController.resetTransform(this);
364
+ setAlpha(1.0f);
365
+ mTintColor = 0;
366
+ mBGDrawable = null;
367
+ mContentDrawable = null;
368
+ mScaleType = AsyncImageView.ScaleType.FIT_XY;
369
+ setImagePositionX(0);
370
+ setImagePositionY(0);
371
+ setAutoFocus(false);
372
+ mUrl = null;
373
+ mImageType = null;
374
+ setBackgroundDrawable(null);
375
+ if (mCustomStateList != null && !mCustomStateList.isEmpty()) {
376
+ //mCustomStateList.clear();
377
+ for(String key:mCustomStateList.keySet()){
378
+ setCustomState(key,false);
379
+ }
380
+ }
381
+ // LogUtils.v("HippyDrawable","resetProps ,this:"+this);
382
+ Arrays.fill(mShouldSendImageEvent, false);
383
+ }
384
+
385
+ @Override
386
+ public void clear() {
387
+ //先解决图片绘制黑屏的问题。 更完全的改法是调用resetProps.
388
+ mTintColor = 0;
389
+ }
390
+
391
+
392
+ /**zhaopeng add*/
393
+ // protected PostHandlerView mPostHandlerView;
394
+ // protected boolean enablePostTask = false;
395
+ // @Override
396
+ // public void setRootPostHandlerView(PostHandlerView pv) {
397
+ // this.mPostHandlerView = pv;
398
+ // }
399
+ // protected boolean isPostTaskEnabled(){
400
+ // return mPostHandlerView != null && enablePostTask;
401
+ // }
402
+
403
+ /**
404
+ * zhaopeng add end
405
+ */
406
+
407
+ public enum ImageEvent {
408
+ ONLOAD,
409
+ ONLOAD_START,
410
+ ONLOAD_END,
411
+ ONERROR
412
+ }
413
+
414
+ protected NativeGestureDispatcher mGestureDispatcher;
415
+
416
+ private OnLoadEvent mOnLoadEvent;
417
+ private OnLoadEndEvent mOnLoadEndEvent;
418
+ private OnErrorEvent mOnErrorEvent;
419
+ private OnLoadStartEvent mOnLoadStartEvent;
420
+ private final boolean[] mShouldSendImageEvent;
421
+ private Rect mNinePatchRect;
422
+ private final HippyEngineContext hippyEngineContext;
423
+
424
+ public HippyImageView(Context context) {
425
+ super(context);
426
+ mShouldSendImageEvent = new boolean[ImageEvent.values().length];
427
+ hippyEngineContext = ((HippyInstanceContext) context).getEngineContext();
428
+ if (hippyEngineContext != null) {
429
+ setImageAdapter(hippyEngineContext.getGlobalConfigs().getImageLoaderAdapter());
430
+ //自定义borderDrawable
431
+ this.borderType = hippyEngineContext.getGlobalConfigs().getEsBaseConfigManager().getFocusBorderType();
432
+ setBorderDrawable(hippyEngineContext.getGlobalConfigs().getBorderDrawableProvider().create());
433
+ }
434
+ //zhaopeng addsetBlackRectEnable
435
+ // focusFrontDrawable = new BorderFrontDrawable();
436
+ // focusFrontDrawable.setBorderVisible(false);
437
+ // focusFrontDrawable.setBlackRectEnable(FocusManagerModule.defaultFocusBorderInnerRectEnable);
438
+ // focusFrontDrawable.setVisible(false, false);
439
+ FocusManagerModule.GlobalFocusConfig focusConfig = FocusManagerModule.getGlobalFocusConfig(hippyEngineContext);
440
+ if (borderDrawable != null) {
441
+ borderDrawable.setBorderVisible(false);
442
+ borderDrawable.setCallback(this);
443
+ borderDrawable.setBlackRectEnable(focusConfig.defaultFocusBorderInnerRectEnable);
444
+ borderDrawable.setVisible(false, false);
445
+ }
446
+ setBlackRectEnable(focusConfig.defaultFocusBorderInnerRectEnable);
447
+ setFocusBorderColor(focusConfig.defaultFocusBorderColor);
448
+ setFocusBorderEnable(focusConfig.defaultFocusBorderEnable);
449
+ setFocusBorderCorner(focusConfig.defaultFocusBorderRadius);
450
+ setFocusBorderWidth(focusConfig.defaultFocusBorderWidth);
451
+ setFocusBorderInset(focusConfig.defaultFocusBorderInset);
452
+ if(focusConfig.defaultBlackFocusBorderRadius != -1){
453
+ borderDrawable.setBlackBorderCorner(focusConfig.defaultBlackFocusBorderRadius);
454
+ }
455
+ if(focusConfig.defaultBlackFocusBorderWidth != -1){
456
+ borderDrawable.setBlackBorderWidth(focusConfig.defaultBlackFocusBorderWidth);
457
+ }
458
+ }
459
+
460
+ @Override
461
+ public void invalidateDrawable(@NonNull Drawable dr) {
462
+ super.invalidateDrawable(dr);
463
+ if (borderDrawable != null && dr == borderDrawable) {
464
+ invalidate();
465
+ }
466
+ }
467
+
468
+ public void initBorderDrawable() {
469
+ if (borderDrawable != null) {
470
+ borderDrawable.setBorderVisible(this.isBorderVisible);
471
+ borderDrawable.setCallback(this);
472
+ borderDrawable.setBlackRectEnable(this.isBlackRectEnable);
473
+ borderDrawable.setVisible(false, false);
474
+ borderDrawable.setBorderColor(this.borderColor);
475
+ borderDrawable.setBorderCorner(this.borderCorner);
476
+ }
477
+ }
478
+
479
+ //设置focusDrawable样式
480
+ public void setFocusBorderType(int type) {
481
+ this.borderType = type;
482
+ if (hippyEngineContext != null) {
483
+ setBorderDrawable(hippyEngineContext.getGlobalConfigs().getBorderDrawableProvider().create());
484
+ initBorderDrawable();
485
+ invalidate();
486
+ }
487
+ }
488
+
489
+ //zhaopeng add
490
+
491
+ /**
492
+ * 设置边框颜色
493
+ *
494
+ * @param color
495
+ */
496
+ public void setFocusBorderColor(@ColorInt int color) {
497
+ if (borderDrawable != null) {
498
+ this.borderColor = color;
499
+ borderDrawable.setBorderColor(color);
500
+ invalidate();
501
+ }
502
+ }
503
+
504
+ /**
505
+ * 设置边框弧度
506
+ *
507
+ * @param
508
+ */
509
+ public void setFocusBorderCorner(float radius) {
510
+ if (borderDrawable != null) {
511
+ this.borderCorner = radius;
512
+ borderDrawable.setBorderCorner(radius);
513
+ invalidate();
514
+ }
515
+ }
516
+
517
+ /**
518
+ * 设置边框宽度
519
+ *
520
+ * @param
521
+ */
522
+ public void setFocusBorderWidth(int width) {
523
+ if (borderDrawable != null && width > -1) {
524
+ this.borderWidth = width;
525
+ borderDrawable.setBorderWidth(width);
526
+ invalidate();
527
+ }
528
+ }
529
+
530
+ /**
531
+ * 设置边框宽度
532
+ *
533
+ * @param
534
+ */
535
+ public void setFocusBorderInset(int inset) {
536
+ if (borderDrawable != null) {
537
+ borderDrawable.setBorderInset(inset);
538
+ invalidate();
539
+ }
540
+ }
541
+
542
+ public void setFocusBorderEnable(boolean enable) {
543
+ if (borderDrawable != null) {
544
+ this.isBorderVisible = enable;
545
+ borderDrawable.setBorderVisible(enable);
546
+ invalidate();
547
+ }
548
+ }
549
+
550
+ public void setBlackRectEnable(boolean enable) {
551
+ if (borderDrawable != null) {
552
+ this.isBlackRectEnable = enable;
553
+ borderDrawable.setBlackRectEnable(enable);
554
+ invalidate();
555
+ }
556
+ }
557
+
558
+ @Override
559
+ public void draw(Canvas canvas) {
560
+ super.draw(canvas);
561
+ if (borderDrawable != null) {
562
+ borderDrawable.onDraw(canvas);
563
+ }
564
+ }
565
+
566
+ //zhaopeng add
567
+
568
+ public void setInitProps(HippyMap props) {
569
+ initProps = props;
570
+ }
571
+
572
+ /**
573
+ * 前端传递下来的参数 left 到左边的距离 right 到右边的距离 top 到上边的距离 botttom 到下边的距离 Robinsli
574
+ */
575
+ public void setNinePatchCoordinate(boolean shouldClearNinePatch, int left, int top, int right,
576
+ int botttom) {
577
+ if (shouldClearNinePatch) {
578
+ mNinePatchRect = null;
579
+ } else {
580
+ if (mNinePatchRect == null) {
581
+ mNinePatchRect = new Rect();
582
+ }
583
+ mNinePatchRect.set(left, top, right, botttom);
584
+ }
585
+ if (mContentDrawable instanceof HippyContentDrawable) {
586
+ ((HippyContentDrawable) mContentDrawable).setNinePatchCoordinate(mNinePatchRect);
587
+ invalidate();
588
+ }
589
+ }
590
+
591
+ public void setImageEventEnable(int index, boolean enable) {
592
+ mShouldSendImageEvent[index] = enable;
593
+ }
594
+
595
+ @Override
596
+ protected void resetContent() {
597
+ super.resetContent();
598
+ // LogUtils.v("HippyDrawable","resetContent ,this:"+this);
599
+ mGifMovie = null;
600
+ mGifProgress = 0;
601
+ mGifLastPlayTime = -1;
602
+ }
603
+
604
+ @Override
605
+ protected boolean shouldUseFetchImageMode(String url) {
606
+ return UrlUtils.isWebUrl(url) || UrlUtils.isFileUrl(url);
607
+ }
608
+
609
+ public void setHippyViewDefaultSource(String defaultSourceUrl) {
610
+ setDefaultSource(defaultSourceUrl);
611
+ }
612
+
613
+ @Override
614
+ protected void doFetchImage(Object param, final int sourceType) {
615
+ if (mImageAdapter != null) {
616
+ if (param == null) {
617
+ param = new HashMap<String, Object>();
618
+ }
619
+
620
+ if (param instanceof Map) {
621
+ if (hippyEngineContext != null) {
622
+ RenderNode node = hippyEngineContext.getRenderManager().getRenderNode(getId());
623
+ if (node != null) {
624
+ initProps = node.getProps();
625
+ }
626
+ }
627
+
628
+ try {
629
+ //noinspection unchecked,rawtypes
630
+ ((Map) param).put(IMAGE_PROPS, initProps);
631
+ //noinspection unchecked,rawtypes
632
+ ((Map) param).put(IMAGE_VIEW_OBJ, this);
633
+ } catch (Exception e) {
634
+ LogUtils.d("HippyImageView", "doFetchImage: " + e);
635
+ }
636
+ }
637
+
638
+ // 这里不判断下是取背景图片还是取当前图片怎么行?
639
+ final String url = sourceType == SOURCE_TYPE_SRC ? mUrl : mDefaultSourceUrl;
640
+ //noinspection unchecked
641
+ mImageAdapter.fetchImage(url, new HippyImageLoader.Callback() {
642
+ @Override
643
+ public void onRequestStart(HippyDrawable drawableTarget) {
644
+ mSourceDrawable = drawableTarget;
645
+ }
646
+
647
+ @Override
648
+ public void onRequestSuccess(HippyDrawable drawableTarget) {
649
+ if (sourceType == SOURCE_TYPE_SRC) {
650
+ if (!TextUtils.equals(url, mUrl)) {
651
+ return;
652
+ }
653
+ mUrlFetchState = IMAGE_LOADED;
654
+ }
655
+
656
+ if (sourceType == SOURCE_TYPE_DEFAULT_SRC && !TextUtils.equals(url, mDefaultSourceUrl)) {
657
+ return;
658
+ }
659
+
660
+ handleImageRequest(drawableTarget, sourceType, null);
661
+ }
662
+
663
+ @Override
664
+ public void onRequestFail(Throwable throwable, String source) {
665
+ if (sourceType == SOURCE_TYPE_SRC) {
666
+ if (!TextUtils.equals(url, mUrl)) {
667
+ return;
668
+ }
669
+ mUrlFetchState = IMAGE_UNLOAD;
670
+ }
671
+
672
+ if (sourceType == SOURCE_TYPE_DEFAULT_SRC && !TextUtils.equals(url, mDefaultSourceUrl)) {
673
+ return;
674
+ }
675
+
676
+ handleImageRequest(null, sourceType, throwable);
677
+ }
678
+ }, param);
679
+ }
680
+ }
681
+
682
+ public void setBackgroundColor(int backgroundColor) {
683
+ mUserHasSetBackgroudnColor = true;
684
+ mUserSetBackgroundColor = backgroundColor;
685
+ // LogUtils.v("HippyDrawable","setBackgroundColor ,this:"+this);
686
+ super.setBackgroundColor(backgroundColor);
687
+ }
688
+
689
+ @Override
690
+ protected void onFetchImage(String url) {
691
+ if (mContentDrawable instanceof ContentDrawable &&
692
+ ((ContentDrawable) mContentDrawable).getSourceType() == SOURCE_TYPE_DEFAULT_SRC) {
693
+ return;
694
+ }
695
+
696
+ Drawable oldBGDrawable = getBackground();
697
+ resetContent();
698
+
699
+
700
+ if (url != null && (UrlUtils.isWebUrl(url) || UrlUtils.isFileUrl(url))) {
701
+ int defaultBackgroundColor = Color.LTGRAY;
702
+ if (mUserHasSetBackgroudnColor) {
703
+ defaultBackgroundColor = mUserSetBackgroundColor;
704
+ }
705
+
706
+ if (oldBGDrawable instanceof CommonBackgroundDrawable) {
707
+ ((CommonBackgroundDrawable) oldBGDrawable).setBackgroundColor(defaultBackgroundColor);
708
+ setCustomBackgroundDrawable((CommonBackgroundDrawable) oldBGDrawable);
709
+ } else if (oldBGDrawable instanceof LayerDrawable) {
710
+ LayerDrawable layerDrawable = (LayerDrawable) oldBGDrawable;
711
+ int numberOfLayers = layerDrawable.getNumberOfLayers();
712
+
713
+ if (numberOfLayers > 0) {
714
+ Drawable bgDrawable = layerDrawable.getDrawable(0);
715
+ if (bgDrawable instanceof CommonBackgroundDrawable) {
716
+ ((CommonBackgroundDrawable) bgDrawable).setBackgroundColor(defaultBackgroundColor);
717
+ setCustomBackgroundDrawable((CommonBackgroundDrawable) bgDrawable);
718
+ }
719
+ }
720
+ }
721
+ super.setBackgroundColor(defaultBackgroundColor);
722
+ mHasSetTempBackgroundColor = true;
723
+ }
724
+ }
725
+
726
+ @Override
727
+ protected void afterSetContent(String url) {
728
+ restoreBackgroundColorAfterSetContent();
729
+ }
730
+
731
+ @Override
732
+ protected void restoreBackgroundColorAfterSetContent() {
733
+ if (mBGDrawable != null && mHasSetTempBackgroundColor) {
734
+ int defaultBackgroundColor = Color.TRANSPARENT;
735
+ mBGDrawable.setBackgroundColor(defaultBackgroundColor);
736
+ // LogUtils.v("HippyDrawable","restoreBackgroundColorAfterSetContent ,this:"+this);
737
+ mHasSetTempBackgroundColor = false;
738
+ }
739
+ }
740
+
741
+ @Override
742
+ protected void updateContentDrawableProperty(int sourceType) {
743
+ super.updateContentDrawableProperty(sourceType);
744
+ if (mContentDrawable instanceof HippyContentDrawable && sourceType == SOURCE_TYPE_SRC) {
745
+ ((HippyContentDrawable) mContentDrawable).setNinePatchCoordinate(mNinePatchRect);
746
+ }
747
+ }
748
+
749
+ @Override
750
+ protected ContentDrawable generateContentDrawable() {
751
+ return new HippyContentDrawable();
752
+ }
753
+
754
+ @Override
755
+ protected BackgroundDrawable generateBackgroundDrawable() {
756
+ return new CommonBackgroundDrawable();
757
+ }
758
+
759
+ @Override
760
+ public boolean onTouchEvent(MotionEvent event) {
761
+ boolean result = super.onTouchEvent(event);
762
+ if (mGestureDispatcher != null) {
763
+ result |= mGestureDispatcher.handleTouchEvent(event);
764
+ }
765
+ return result;
766
+ }
767
+
768
+ @Override
769
+ public NativeGestureDispatcher getGestureDispatcher() {
770
+ return mGestureDispatcher;
771
+ }
772
+
773
+ @Override
774
+ public void setGestureDispatcher(NativeGestureDispatcher dispatcher) {
775
+ mGestureDispatcher = dispatcher;
776
+ }
777
+
778
+ @Override
779
+ protected void handleGetImageStart() {
780
+ // send onLoadStart event
781
+ super.handleGetImageStart();
782
+ if (mShouldSendImageEvent[ImageEvent.ONLOAD_START.ordinal()]) {
783
+ getOnLoadStartEvent().send(this, null);
784
+ }
785
+ onBindNew = false;
786
+ if (mCustomStateListener != null) {
787
+ mCustomStateListener.onRequestStart(this);
788
+ }
789
+ }
790
+
791
+ @Override
792
+ protected void handleGetImageSuccess() {
793
+ // send onLoad event
794
+ if (mShouldSendImageEvent[ImageEvent.ONLOAD.ordinal()]) {
795
+ getOnLoadEvent().send(this, null);
796
+ }
797
+ if(mCustomStateListener != null) {
798
+ mCustomStateListener.onRequestSuccess(this);
799
+ }
800
+ // send onLoadEnd event
801
+ if (mShouldSendImageEvent[ImageEvent.ONLOAD_END.ordinal()]) {
802
+ HippyMap map = new HippyMap();
803
+ map.pushInt("success", 1);
804
+ if (mSourceDrawable != null) {
805
+ Bitmap bitmap = mSourceDrawable.getBitmap();
806
+ HippyMap imageSize = new HippyMap();
807
+ if (bitmap != null) {
808
+ imageSize.pushInt("width", bitmap.getWidth());
809
+ imageSize.pushInt("height", bitmap.getHeight());
810
+ } else {
811
+ imageSize.pushInt("width", 0);
812
+ imageSize.pushInt("height", 0);
813
+ }
814
+ map.pushMap("image", imageSize);
815
+ } else {
816
+ HippyMap imageSize = new HippyMap();
817
+ imageSize.pushInt("width", 0);
818
+ imageSize.pushInt("height", 0);
819
+ map.pushMap("image", imageSize);
820
+ }
821
+ getOnLoadEndEvent().send(this, map);
822
+ }
823
+ }
824
+
825
+ @Override
826
+ protected void handleGetImageFail(Throwable throwable) {
827
+ // send onError event
828
+ if (mShouldSendImageEvent[ImageEvent.ONERROR.ordinal()]) {
829
+ getOnErrorEvent().send(this, null);
830
+ }
831
+ // send onLoadEnd event
832
+ if (mShouldSendImageEvent[ImageEvent.ONLOAD_END.ordinal()]) {
833
+ HippyMap map = new HippyMap();
834
+ map.pushInt("success", 0);
835
+ getOnLoadEndEvent().send(this, map);
836
+ }
837
+ onBindNew = false;
838
+ if (mCustomStateListener != null) {
839
+ mCustomStateListener.onRequestFail(throwable, getUrl());
840
+ }
841
+ }
842
+
843
+ private void computeMatrixParams() {
844
+ if (!mGifMatrixComputed) {
845
+ // reset
846
+ mGifStartX = 0;
847
+ mGifStartY = 0;
848
+ mGifScaleX = 1;
849
+ mGifScaleY = 1;
850
+ if (mGifMovie.width() > 0 && mGifMovie.height() > 0 && getWidth() > 0 && getHeight() > 0) {
851
+ mGifScaleX = getWidth() / (float) mGifMovie.width();
852
+ mGifScaleY = getHeight() / (float) mGifMovie.height();
853
+ }
854
+ ScaleType type = mScaleType != null ? mScaleType : ScaleType.FIT_XY;
855
+ switch (type) {
856
+ case FIT_XY:
857
+ // 拉伸图片且不维持宽高比,直到宽高都刚好填满容器
858
+ break;
859
+ case CENTER:
860
+ // 居中不拉伸
861
+ mGifScaleX = 1;
862
+ mGifScaleY = 1;
863
+ break;
864
+ case CENTER_INSIDE:
865
+ // 在保持图片宽高比的前提下缩放图片,直到宽度和高度都小于等于容器视图的尺寸
866
+ // 这样图片完全被包裹在容器中,容器中可能留有空白
867
+ if (mGifScaleX > mGifScaleY) {
868
+ //noinspection SuspiciousNameCombination
869
+ mGifScaleX = mGifScaleY;
870
+ } else {
871
+ //noinspection SuspiciousNameCombination
872
+ mGifScaleY = mGifScaleX;
873
+ }
874
+ break;
875
+ case CENTER_CROP:
876
+ // 在保持图片宽高比的前提下缩放图片,直到宽度和高度都大于等于容器视图的尺寸
877
+ // 这样图片完全覆盖甚至超出容器,容器中不留任何空白
878
+ if (mGifScaleX < mGifScaleY) {
879
+ //noinspection SuspiciousNameCombination
880
+ mGifScaleX = mGifScaleY;
881
+ } else {
882
+ //noinspection SuspiciousNameCombination
883
+ mGifScaleY = mGifScaleX;
884
+ }
885
+ break;
886
+ case ORIGIN:
887
+ mGifScaleX = mGifScaleY = 1;
888
+ // 不拉伸,居左上
889
+ break;
890
+ }
891
+ if (mScaleType != ScaleType.ORIGIN) {
892
+ mGifStartX = (int) ((getWidth() / mGifScaleX - mGifMovie.width()) / 2f);
893
+ mGifStartY = (int) ((getHeight() / mGifScaleY - mGifMovie.height()) / 2f);
894
+ }
895
+ mGifMatrixComputed = true;
896
+ }
897
+ }
898
+
899
+ @Override
900
+ protected void handleImageRequest(IDrawableTarget target, int sourceType, Object requestInfo) {
901
+ if (target != null && !TextUtils.isEmpty(target.getImageType())) {
902
+ mImageType = target.getImageType();
903
+ }
904
+
905
+ if (target instanceof HippyDrawable && ((HippyDrawable) target).isAnimated()) {
906
+ mGifMovie = ((HippyDrawable) target).getGIF();
907
+ setLayerType(View.LAYER_TYPE_SOFTWARE, null);
908
+ }
909
+
910
+ if (!TextUtils.isEmpty(mImageType) && mImageType.equals(IMAGE_TYPE_APNG)
911
+ && sourceType == SOURCE_TYPE_SRC) {
912
+ if (target != null) {
913
+ Drawable drawable = target.getDrawable();
914
+ if (drawable != null) {
915
+ mSourceDrawable = null;
916
+ mContentDrawable = drawable;
917
+ mUrlFetchState = IMAGE_LOADED;
918
+ setContent(sourceType);
919
+ handleGetImageSuccess();
920
+ return;
921
+ }
922
+ }
923
+
924
+ mUrlFetchState = IMAGE_UNLOAD;
925
+ handleGetImageFail(requestInfo instanceof Throwable ? (Throwable) requestInfo : null);
926
+ } else {
927
+ super.handleImageRequest(target, sourceType, requestInfo);
928
+ }
929
+ }
930
+
931
+ protected boolean drawGIF(Canvas canvas) {
932
+ if (mGifMovie == null) {
933
+ return false;
934
+ }
935
+
936
+ int duration = mGifMovie.duration();
937
+ if (duration == 0) {
938
+ duration = 1000;
939
+ }
940
+
941
+ long now = System.currentTimeMillis();
942
+
943
+ if (!isGifPaused) {
944
+ if (mGifLastPlayTime != -1) {
945
+ mGifProgress += now - mGifLastPlayTime;
946
+
947
+ if (mGifProgress > duration) {
948
+ mGifProgress = 0;
949
+ }
950
+ }
951
+ mGifLastPlayTime = now;
952
+ }
953
+
954
+ computeMatrixParams();
955
+ mGifMovie.setTime(mGifProgress);
956
+ canvas.save(); // 保存变换矩阵
957
+ canvas.scale(mGifScaleX, mGifScaleY);
958
+ mGifMovie.draw(canvas, mGifStartX, mGifStartY);
959
+ canvas.restore(); // 恢复变换矩阵
960
+
961
+ if (!isGifPaused) {
962
+ postInvalidateDelayed(40);
963
+ }
964
+
965
+ return true;
966
+ }
967
+
968
+ protected boolean shouldFetchImage() {
969
+ if (mUrlFetchState == IMAGE_LOADING) {
970
+ return onBindNew;
971
+ } else if (mUrlFetchState == IMAGE_UNLOAD) {
972
+ return true;
973
+ }
974
+
975
+ boolean isGif = (initProps != null) && initProps.getBoolean(NodeProps.CUSTOM_PROP_ISGIF);
976
+ if (!isGif) {
977
+ isGif = !TextUtils.isEmpty(mImageType) && mImageType.equals(IMAGE_TYPE_GIF);
978
+ }
979
+
980
+ if (!TextUtils.isEmpty(mImageType) && mImageType.equals(IMAGE_TYPE_APNG)
981
+ && mContentDrawable != null && !(mContentDrawable instanceof ContentDrawable)) {
982
+ return onBindNew;
983
+ } else if (isGif) {
984
+ return mGifMovie == null || onBindNew;
985
+ } else {
986
+ Bitmap bitmap = getBitmap();
987
+ //noinspection RedundantIfStatement
988
+ if (bitmap == null || bitmap.isRecycled()) {
989
+ return true;
990
+ }
991
+ }
992
+
993
+ return onBindNew;
994
+ }
995
+
996
+ // 图片自绘功能(方便自定义支持gif、webp、tpg等)尚未实现,暂时注释
997
+ // private void drawSelf(Canvas canvas, HippyDrawable drawable) {
998
+ // computeMatrixParams();
999
+ // canvas.save(); // 保存变换矩阵
1000
+ //
1001
+ // canvas.clipRect(new Rect(mGifStartX, mGifStartY, canvas.getWidth(), canvas.getHeight()));
1002
+ // canvas.scale(mGifScaleX, mGifScaleY);
1003
+ //
1004
+ // drawable.draw(canvas);
1005
+ //
1006
+ // // canvas.restore(); // 恢复变换矩阵
1007
+ // postInvalidateDelayed(40);
1008
+ // }
1009
+
1010
+
1011
+ @Override
1012
+ protected void onDetachedFromWindow() {
1013
+ super.onDetachedFromWindow();
1014
+ if (isFocusable() && borderDrawable != null) {
1015
+ borderDrawable.onDetachedFromWindow(this);
1016
+ }
1017
+ }
1018
+
1019
+ @Override
1020
+ public void onDraw(Canvas canvas) {
1021
+ super.onDraw(canvas);
1022
+ // 图片自绘功能(方便自定义支持gif、webp、tpg等)尚未实现,暂时注释
1023
+ // if (mSourceDrawable instanceof HippyDrawable)
1024
+ // {
1025
+ // HippyDrawable drawable = (HippyDrawable) mSourceDrawable;
1026
+ // if (drawable.isSelfDraw())
1027
+ // drawSelf(canvas, drawable);
1028
+ // }
1029
+ // else
1030
+ if (mGifMovie != null) {
1031
+ // 如果是GIF,就调用drawGIF()方法播放GIF动画
1032
+ drawGIF(canvas);
1033
+ }
1034
+ }
1035
+
1036
+ private boolean isGifPaused = false;
1037
+
1038
+ public void startPlay() {
1039
+ isGifPaused = false;
1040
+ invalidate();
1041
+ }
1042
+
1043
+ public void pause() {
1044
+ isGifPaused = true;
1045
+ mGifLastPlayTime = -1;
1046
+ }
1047
+
1048
+ @Override
1049
+ public void notifySaveState() {
1050
+
1051
+ }
1052
+
1053
+ @Override
1054
+ public void notifyRestoreState() {
1055
+
1056
+ }
1057
+
1058
+ private OnLoadEvent getOnLoadEvent() {
1059
+ if (mOnLoadEvent == null) {
1060
+ mOnLoadEvent = new OnLoadEvent();
1061
+ }
1062
+ return mOnLoadEvent;
1063
+ }
1064
+
1065
+ private OnLoadEndEvent getOnLoadEndEvent() {
1066
+ if (mOnLoadEndEvent == null) {
1067
+ mOnLoadEndEvent = new OnLoadEndEvent();
1068
+ }
1069
+ return mOnLoadEndEvent;
1070
+ }
1071
+
1072
+ private OnLoadStartEvent getOnLoadStartEvent() {
1073
+ if (mOnLoadStartEvent == null) {
1074
+ mOnLoadStartEvent = new OnLoadStartEvent();
1075
+ }
1076
+ return mOnLoadStartEvent;
1077
+ }
1078
+
1079
+ private OnErrorEvent getOnErrorEvent() {
1080
+ if (mOnErrorEvent == null) {
1081
+ mOnErrorEvent = new OnErrorEvent();
1082
+ }
1083
+ return mOnErrorEvent;
1084
+ }
1085
+
1086
+ /**
1087
+ * event to js
1088
+ **/
1089
+ static class OnLoadEvent extends HippyViewEvent {
1090
+
1091
+ OnLoadEvent() {
1092
+ super("onLoad");
1093
+ }
1094
+ }
1095
+
1096
+ static class OnLoadEndEvent extends HippyViewEvent {
1097
+
1098
+ OnLoadEndEvent() {
1099
+ super("onLoadEnd");
1100
+ }
1101
+ }
1102
+
1103
+ static class OnLoadStartEvent extends HippyViewEvent {
1104
+
1105
+ OnLoadStartEvent() {
1106
+ super("onLoadStart");
1107
+ }
1108
+ }
1109
+
1110
+ static class OnErrorEvent extends HippyViewEvent {
1111
+
1112
+ OnErrorEvent() {
1113
+ super("onError");
1114
+ }
1115
+ }
1116
+
1117
+ /**
1118
+ * add by zhaopeng 20201110
1119
+ */
1120
+
1121
+
1122
+ private int mDuration = TVFocusScaleExcuter.DEFAULT_DURATION;
1123
+ private float mFocusScaleX = FocusManagerModule.defaultFocusScale;
1124
+ private float mFocusScaleY = FocusManagerModule.defaultFocusScale;
1125
+
1126
+ private final AttachInfo mAttachInfo = new AttachInfo();
1127
+
1128
+ /**
1129
+ * -------------------------------------------------------------------------------------
1130
+ **/
1131
+
1132
+ @Override
1133
+ public void onHandleFocusScale(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
1134
+ if (isFocusable() && mFocusScaleX != 1 || mFocusScaleY != 1) {
1135
+ handleFocusScale(gainFocus, direction, previouslyFocusedRect, mDuration);
1136
+ }
1137
+
1138
+ }
1139
+
1140
+
1141
+ public void handleFocusScale(boolean gainFocus, int direction, Rect previouslyFocusedRect, int duration) {
1142
+ if ((mFocusScaleX != 1 || mFocusScaleY != 1)) {
1143
+ AutoFocusManager af = AutoFocusManager.findAutoFocusManagerFromRoot(this);
1144
+ if (af != null) {
1145
+ af.handleOnFocusChange(this, gainFocus, mFocusScaleX, mFocusScaleY, duration);
1146
+ }else {
1147
+ TVFocusScaleExcuter.handleOnFocusChange(this, gainFocus, mFocusScaleX, mFocusScaleY, duration);
1148
+ }
1149
+ }
1150
+ }
1151
+
1152
+ public void handleFocusScaleImmediately(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
1153
+ if (isFocusable() && (mFocusScaleX != 1 || mFocusScaleY != 1)) {
1154
+ // Log.e("zhaopeng","!!!!!!handleFocusScaleImmediately gainFocus:"+gainFocus);
1155
+ TVFocusScaleExcuter.handleOnFocusChange(this, gainFocus, mFocusScaleX, mFocusScaleY, 0);
1156
+ }
1157
+ }
1158
+
1159
+ @Override
1160
+ public Rect getFloatFocusMarginRect() {
1161
+ return mAttachInfo.mFloatFocusMarginRect;
1162
+ }
1163
+
1164
+
1165
+ /**
1166
+ * {@link ITVView#setFocusScale(float)}
1167
+ *
1168
+ * @param scale 缩放倍数
1169
+ */
1170
+ @Override
1171
+ public void setFocusScale(float scale) {
1172
+ this.mFocusScaleX = scale;
1173
+ this.mFocusScaleY = scale;
1174
+ }
1175
+
1176
+
1177
+ /**
1178
+ * 设置View获得焦点的放大倍数
1179
+ */
1180
+ @Override
1181
+ public void setFocusScaleX(float scale) {
1182
+ this.mFocusScaleX = scale;
1183
+ }
1184
+
1185
+ /**
1186
+ * 设置View获得焦点的放大倍数
1187
+ */
1188
+ @Override
1189
+ public void setFocusScaleY(float scale) {
1190
+ this.mFocusScaleY = scale;
1191
+ }
1192
+
1193
+
1194
+ /**
1195
+ * {@link ITVView#setFocusScaleDuration(int)}
1196
+ *
1197
+ * @param duration 缩放动画时长 单位:毫秒
1198
+ */
1199
+ @Override
1200
+ public void setFocusScaleDuration(int duration) {
1201
+ this.mDuration = duration;
1202
+ }
1203
+
1204
+ @Override
1205
+ public float getFocusScale() {
1206
+ return mFocusScaleX ;
1207
+ }
1208
+
1209
+ @Override
1210
+ public float getFocusScaleX() {
1211
+ return mFocusScaleX;
1212
+ }
1213
+
1214
+ @Override
1215
+ public float getFocusScaleY() {
1216
+ return mFocusScaleY;
1217
+ }
1218
+
1219
+ @Override
1220
+ public IFloatFocusManager getFloatFocusManager() {
1221
+ return null;
1222
+ }
1223
+
1224
+ @Override
1225
+ public void setFloatFocusFocusedAlpha(float alpha) {
1226
+ mAttachInfo.setFloatFocusFocusedAlpha(alpha);
1227
+ }
1228
+
1229
+ @Override
1230
+ public AttachInfo getAttachInfo() {
1231
+ return mAttachInfo;
1232
+ }
1233
+
1234
+ @Override
1235
+ public View getView() {
1236
+ return this;
1237
+ }
1238
+
1239
+
1240
+ protected int getUserSetBackgroundColor() {
1241
+ return mUserSetBackgroundColor;
1242
+ }
1243
+
1244
+ private boolean mInReFocus = false;
1245
+
1246
+ @Override
1247
+ public void notifyInReFocus(boolean isIn) {
1248
+ this.mInReFocus = isIn;
1249
+ // Log.d("zhaopeng"," notifyInReFocus :"+isIn+" this:"+this);
1250
+ if (!isFocusable()) {
1251
+ for (int i = 0; i < getChildCount(); i++) {
1252
+ final View child = getChildAt(i);
1253
+ if (child instanceof ITVView) {
1254
+ ((ITVView) child).notifyInReFocus(isIn);
1255
+ }
1256
+ }
1257
+ }
1258
+ }
1259
+
1260
+ @Override
1261
+ protected void onFocusChanged(boolean gainFocus, int direction, @Nullable Rect previouslyFocusedRect) {
1262
+ super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
1263
+ if (borderDrawable != null && isBorderVisible) {
1264
+ borderDrawable.onFocusChanged(this, gainFocus);
1265
+ }
1266
+ }
1267
+
1268
+ @Override
1269
+ public boolean isInReFocus() {
1270
+ return mInReFocus;
1271
+ }
1272
+
1273
+ private int mUserSetFocusBackgroundColor = 0;
1274
+ private int mUserSetSelectBackgroundColor = 0;
1275
+ private boolean relayoutAfterAttach = false;
1276
+
1277
+
1278
+ /***
1279
+ *
1280
+ * @param color
1281
+ */
1282
+ public void setFocusBackGroundColor(int color) {
1283
+ this.mUserSetFocusBackgroundColor = color;
1284
+ // invalidate();
1285
+ drawableStateChanged();
1286
+ }
1287
+
1288
+ /***
1289
+ *
1290
+ * @param color
1291
+ */
1292
+ public void setSelectBackGroundColor(int color) {
1293
+ this.mUserSetSelectBackgroundColor = color;
1294
+ // invalidate();
1295
+ drawableStateChanged();
1296
+ }
1297
+
1298
+
1299
+ public void setRelayoutAfterAttach(boolean relayoutAfterAttach) {
1300
+ this.relayoutAfterAttach = relayoutAfterAttach;
1301
+ }
1302
+
1303
+ @Override
1304
+ protected void onAttachedToWindow() {
1305
+ super.onAttachedToWindow();
1306
+ if (selectState) {
1307
+ setSelected(true);
1308
+ }
1309
+ if (relayoutAfterAttach) {
1310
+ if (getWidth() <= 0 || getHeight() <= 0) {
1311
+ if (getContext() instanceof HippyInstanceContext) {
1312
+ final HippyEngineContext context = ((HippyInstanceContext) getContext()).getEngineContext();
1313
+ if (context != null) {
1314
+ final RenderNode node = context.getRenderManager().getRenderNode(getId());
1315
+ if (node != null && !node.isDelete()) {
1316
+ node.updateLayout(node.getX(), node.getY(), node.getWidth(), node.getHeight());
1317
+ node.updateViewRecursive();
1318
+ }
1319
+ }
1320
+ }
1321
+ }
1322
+ }
1323
+ //Log.v(AutoFocusManager.TAG, "------onAttachedToWindow this:" + this + ",isAttached:" + isAttached()+",width:"+getWidth());
1324
+ if(getWidth() > 0 && getHeight() > 0 && getVisibility() == View.VISIBLE){
1325
+ if(AutoFocusManager.isAutofocusView(this)) {
1326
+ if(LogUtils.isDebug()) {
1327
+ Log.i(AutoFocusManager.TAG, "auto requestFocus on onAttachedToWindow ,view:" + this);
1328
+ }
1329
+ onRequestAutofocus(this, this,ExtendViewGroup.AUTOFOCUS_TYPE_ATTACH);
1330
+ }
1331
+ }
1332
+ // LogUtils.v("HippyDrawable","onAttachedToWindow ,this:"+this);
1333
+ }
1334
+
1335
+ @Override
1336
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
1337
+ super.onSizeChanged(w, h, oldw, oldh);
1338
+ if (borderDrawable != null) {
1339
+ borderDrawable.onSizeChanged(w, h, oldw, oldh);
1340
+ }
1341
+ for(int i = 0; i < getChildCount(); i ++){
1342
+ final View v = getChildAt(i);
1343
+ if(v instanceof ITVView){
1344
+ final ITVView cv = (ITVView) v;
1345
+ if(cv.isFillParent()){
1346
+ cv.getView().layout(0,0,w,h);
1347
+ //layoutChildrenLegacy(cv.getView(),l,t,r,b);
1348
+ if(LogUtils.isDebug()) {
1349
+ Log.d(CustomLayoutView.TAG, "layout fill child:" + cv.getView());
1350
+ }
1351
+ }
1352
+ }
1353
+ }
1354
+
1355
+ if(oldw < 1 && oldh < 1 && w > 0 && h > 0){
1356
+ //Log.v(AutoFocusManager.TAG,"------onSizeChanged this:"+this+",isAttached:"+isAttached());
1357
+ //v-show变化后
1358
+ if(globalVisibility == View.VISIBLE && getVisibility() == View.VISIBLE && isAttached()){
1359
+ //AutoFocusManager.globalRequestFocus(this);
1360
+ if(AutoFocusManager.isAutofocusView(this)) {
1361
+ if(LogUtils.isDebug()) {
1362
+ Log.i(AutoFocusManager.TAG, "auto requestFocus on size changed ,view:" + ExtendUtil.debugView(this));
1363
+ }
1364
+ onRequestAutofocus(this, this,ExtendViewGroup.AUTOFOCUS_TYPE_SIZE_VALID);
1365
+ }
1366
+ }
1367
+ //这里由于设置backgroundColorStr背景色,在尺寸0的时候不生效,所以这里再设置一下。
1368
+ ExtendTag tag = ExtendTag.getExtendTag(this);
1369
+ if(tag!= null && tag.pendingBackGroundColor != -1){
1370
+ setBackgroundColor(tag.pendingBackGroundColor);
1371
+ tag.pendingBackGroundColor = -1;
1372
+ }
1373
+
1374
+ //if(AutoFocusManager.)
1375
+ }
1376
+ }
1377
+
1378
+ public void onRequestAutofocus(View child, View target, int type) {
1379
+ if(child.getParent() instanceof ExtendViewGroup){
1380
+ ExtendViewGroup parent = (ExtendViewGroup) child.getParent();
1381
+ parent.onRequestAutofocus(child,target,type);
1382
+ }else{
1383
+ Log.i(AutoFocusManager.TAG,"onRequestAutofocus parent is not a instance of ExtendViewGroup parent: "+getParent());
1384
+ }
1385
+ }
1386
+
1387
+ @Override
1388
+ protected void onDrawableAttached() {
1389
+ super.onDrawableAttached();
1390
+ }
1391
+
1392
+ protected void onChangeShowOnState() {
1393
+
1394
+ }
1395
+
1396
+ private Runnable updateBGTask;
1397
+
1398
+ private void postSetBGColor(final int bg) {
1399
+ // if(updateBGTask != null){
1400
+ // removeCallbacks(updateBGTask);
1401
+ // }
1402
+ // updateBGTask = () -> {
1403
+ // getBackgroundDrawable().setBackgroundColor(bg);
1404
+ // invalidate();
1405
+ // };
1406
+ // postDelayed(updateBGTask,16);
1407
+ getBackgroundDrawable().setBackgroundColor(bg);
1408
+ postInvalidateDelayed(16);
1409
+ // invalidate();
1410
+ }
1411
+
1412
+
1413
+
1414
+ @Override
1415
+ protected void drawableStateChanged() {
1416
+ super.drawableStateChanged();
1417
+ int[] states = getDrawableState();
1418
+
1419
+
1420
+ if (!isFocused() && isDuplicateParentStateEnabled()) {
1421
+ final boolean focused = ExtendUtil.stateContainsAttribute(states, android.R.attr.state_focused);
1422
+ if(isBorderVisible){
1423
+ if (borderDrawable != null) {
1424
+ borderDrawable.onDrawableStateChanged(this, focused);
1425
+ }
1426
+ }
1427
+ if (focusScaleOnDuplicateParentState && (mFocusScaleX != 1 || mFocusScaleY != 1)) {
1428
+ //TVFocusScaleExcuter.handleOnFocusChange(this, focused, mFocusScaleX, mFocusScaleY, mDuration);
1429
+ // onHandleFocusScale();
1430
+ handleFocusScale(focused,-1,null,mDuration);
1431
+ }
1432
+ }
1433
+ if (ExtendUtil.handleShowOnState(this, states, showOnState)) {
1434
+ onChangeShowOnState();
1435
+ }
1436
+ ExtendUtil.handleCustomShowOnState(this, mCustomStateList,showOnStateCustom);
1437
+ // if(showOnState == null && isDuplicateParentStateEnabled()) {
1438
+ // if(LogUtils.isDebug()) {
1439
+ // LogUtils.e("HippyDrawable", "isDuplicateParentStateEnabled0 ,this:" + hashCode() + ",showOnState is NULL");
1440
+ // }
1441
+ // }
1442
+ // else{
1443
+ // LogUtils.v("HippyDrawable", "isDuplicateParentStateEnabled0 ,this:" + hashCode() + ",showOnState length:" + showOnState.length);
1444
+ // }
1445
+ if (isFocusable() || isDuplicateParentStateEnabled()) {
1446
+ if (mUserSetFocusBackgroundColor != 0) {
1447
+
1448
+ final boolean focused = ExtendUtil.stateContainsAttribute(states, android.R.attr.state_focused);
1449
+ if (focused || isFocused()) {
1450
+ postSetBGColor(mUserSetFocusBackgroundColor);
1451
+ return;
1452
+ }
1453
+ }
1454
+
1455
+ final boolean select = ExtendUtil.stateContainsAttribute(states, android.R.attr.state_selected);
1456
+ if (mUserSetSelectBackgroundColor != 0) {
1457
+ if (select || isSelected()) {
1458
+ postSetBGColor(mUserSetSelectBackgroundColor);
1459
+ return;
1460
+ }
1461
+ }
1462
+ if (mUrlFetchState != IMAGE_LOADED || onBindNew || getId() != -1) {
1463
+ //zhaopeng 因为图片已经加载成功,直接展示图片,不需要再展示背景
1464
+ //getId != -1的判断是由于在fastList里会走onBindNew,而在普通的img标签上却没有机会执行,所以这里做一下修正
1465
+ postSetBGColor(getUserSetBackgroundColor());
1466
+ } else {
1467
+ postInvalidateDelayed(16);
1468
+ }
1469
+ }
1470
+ }
1471
+
1472
+ @Override
1473
+ public void getState(@NonNull HippyMap map) {
1474
+ if (getBitmap() != null) {
1475
+ map.pushInt("imgWidth", getBitmap().getWidth());
1476
+ map.pushInt("imgHeight", getBitmap().getHeight());
1477
+ }
1478
+ }
1479
+
1480
+ private int[] showOnState;
1481
+
1482
+
1483
+ @Override
1484
+ public void setShowOnState(int[] showOnState) {
1485
+ if (LogUtils.isDebug()) {
1486
+ LogUtils.i("HippyDrawable", "setShowOnState ,showOnState size:" + showOnState.length + ",this:" + hashCode());
1487
+ }
1488
+ this.showOnState = showOnState;
1489
+ }
1490
+
1491
+ /** custom showOnState
1492
+ * --------------------
1493
+ */
1494
+ private String[] showOnStateCustom;
1495
+ ArrayMap<String,Boolean> mCustomStateList = null;
1496
+ @Override
1497
+ public void setCustomState(String state, boolean on) {
1498
+ if (mCustomStateList == null) {
1499
+ mCustomStateList = new ArrayMap<>();
1500
+ }
1501
+ mCustomStateList.put(state,on);
1502
+ if("selected".equals(state)){
1503
+ setSelectState(on);
1504
+ }
1505
+ Log.i("CustomState","setCustomState state:"+state+" on:"+on+" this:"+ExtendUtil.debugViewLite(this));
1506
+ changeChildrenCustomState(this,state,on);
1507
+ refreshDrawableState();
1508
+ }
1509
+
1510
+ void changeChildrenCustomState(ViewGroup view,String state, boolean on){
1511
+ for (int i = 0; i < view.getChildCount(); i++) {
1512
+ View child = view.getChildAt(i);
1513
+ if (child.isDuplicateParentStateEnabled()) {
1514
+ if (child instanceof StateView) {
1515
+ ((StateView) child).setCustomState(state, on);
1516
+ } else if (child instanceof ViewGroup) {
1517
+ changeChildrenCustomState((ViewGroup) child, state, on);
1518
+ }
1519
+ }
1520
+ }
1521
+ }
1522
+
1523
+
1524
+ @Override
1525
+ public void setShowOnCustomState(String[] showOnState) {
1526
+ this.showOnStateCustom = showOnState;
1527
+ }
1528
+
1529
+ /**custom showOnState
1530
+ * ----------------
1531
+ */
1532
+ /**
1533
+ * -------------------------------------------------------------------------------------
1534
+ **/
1535
+
1536
+ public void setSelectState(boolean selectState) {
1537
+ this.selectState = selectState;
1538
+ setSelected(selectState);
1539
+ }
1540
+
1541
+
1542
+
1543
+ @Override
1544
+ public void setSelected(boolean selected) {
1545
+ super.setSelected(selected);
1546
+ if (showOnState != null && showOnState.length > 0) {
1547
+ HippyMap hippyMap = new HippyMap();
1548
+ hippyMap.pushBoolean("isSelected", selected);
1549
+ new HippyViewEvent("onSelect").send(this, hippyMap);
1550
+ }
1551
+ }
1552
+
1553
+
1554
+ @Override
1555
+ public void setFillParent(boolean b) {
1556
+ isFillParent = b;
1557
+ }
1558
+
1559
+ @Override
1560
+ public boolean isFillParent() {
1561
+ return isFillParent;
1562
+ }
1563
+
1564
+
1565
+
1566
+ @Override
1567
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
1568
+ super.onLayout(changed, l, t, r, b);
1569
+ if(changed){
1570
+ if (mCustomStateListener != null) {
1571
+ mCustomStateListener.onImageLayout(this, l, t, r, b);
1572
+ }
1573
+ }
1574
+ }
1575
+
1576
+ @Override
1577
+ public void notifyBringToFront(boolean b) {
1578
+
1579
+ }
1580
+
1581
+ //这里暂不需要
1582
+ // static void layoutChildrenLegacy(View view,int l, int t, int r, int b){
1583
+ // if(!(view instanceof ViewGroup)){
1584
+ // return;
1585
+ // }
1586
+ // for(int i = 0; i < ((ViewGroup) view).getChildCount(); i ++){
1587
+ // final View child = ((ViewGroup) view).getChildAt(i);
1588
+ // LayoutParams lp = child.getLayoutParams();
1589
+ // int cl,ct,cr,cb;cl = ct= cr = cb = 0;
1590
+ // if (lp != null) {
1591
+ // if(lp.width == LayoutParams.MATCH_PARENT){
1592
+ // cr = r - l;
1593
+ // }
1594
+ // if(lp.height == LayoutParams.MATCH_PARENT){
1595
+ // cb = b - t ;
1596
+ // }
1597
+ // }else {
1598
+ // cr = r - l;
1599
+ // cb = b - t;
1600
+ // }
1601
+ // Log.e(CustomLayoutView.TAG,"layoutChildrenLegacy left:"+cl+",top :"+ct+",right :"+cr+",b:"+cb);
1602
+ // RenderUtil.layoutView(child,cl,ct,cr,cb);
1603
+ // layoutChildrenLegacy(child,cl,ct,cr,cb);
1604
+ //
1605
+ // }
1606
+ // }
1607
+
1608
+ }