@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,915 @@
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.list;
17
+
18
+ import android.graphics.Canvas;
19
+ import android.view.ViewConfiguration;
20
+
21
+ import com.tencent.mtt.hippy.HippyEngineContext;
22
+ import com.tencent.mtt.hippy.HippyInstanceContext;
23
+ import com.tencent.mtt.hippy.common.HippyMap;
24
+ import com.tencent.mtt.hippy.uimanager.HippyViewBase;
25
+ import com.tencent.mtt.hippy.uimanager.HippyViewEvent;
26
+ import com.tencent.mtt.hippy.uimanager.NativeGestureDispatcher;
27
+ import com.tencent.mtt.hippy.uimanager.RenderNode;
28
+ import com.tencent.mtt.hippy.utils.LogUtils;
29
+ import com.tencent.mtt.hippy.utils.PixelUtil;
30
+ import com.tencent.mtt.hippy.views.refresh.HippyPullFooterView;
31
+ import com.tencent.mtt.hippy.views.refresh.HippyPullHeaderView;
32
+ import com.tencent.mtt.hippy.views.scroll.HippyScrollViewEventHelper;
33
+ import com.tencent.mtt.supportui.views.recyclerview.BaseLayoutManager;
34
+ import com.tencent.mtt.supportui.views.recyclerview.LinearLayoutManager;
35
+ import com.tencent.mtt.supportui.views.recyclerview.RecyclerView;
36
+ import com.tencent.mtt.supportui.views.recyclerview.RecyclerViewItem;
37
+
38
+ import android.content.Context;
39
+ import android.view.MotionEvent;
40
+ import android.view.View;
41
+ import android.view.ViewTreeObserver;
42
+
43
+ @SuppressWarnings({"deprecation", "unused"})
44
+ public class HippyListView extends RecyclerView implements HippyViewBase {
45
+
46
+ public final static int REFRESH_STATE_IDLE = 0;
47
+ public final static int REFRESH_STATE_LOADING = 1;
48
+
49
+ public static final String EVENT_TYPE_HEADER_RELEASED = "onHeaderReleased";
50
+ public static final String EVENT_TYPE_HEADER_PULLING = "onHeaderPulling";
51
+
52
+ public static final String EVENT_TYPE_FOOTER_RELEASED = "onFooterReleased";
53
+ public static final String EVENT_TYPE_FOOTER_PULLING = "onFooterPulling";
54
+
55
+ protected int mHeaderRefreshState = REFRESH_STATE_IDLE;
56
+ protected int mFooterRefreshState = REFRESH_STATE_IDLE;
57
+ protected final boolean mEnableRefresh = true;
58
+
59
+ private HippyListAdapter mListAdapter;
60
+
61
+ private HippyEngineContext mHippyContext;
62
+
63
+ private NativeGestureDispatcher mGestureDispatcher;
64
+
65
+ protected boolean mScrollBeginDragEventEnable = false;
66
+
67
+ protected boolean mScrollEndDragEventEnable = false;
68
+
69
+ protected boolean mMomentumScrollBeginEventEnable = false;
70
+
71
+ protected boolean mMomentumScrollEndEventEnable = false;
72
+
73
+ protected boolean mScrollEventEnable = true;
74
+
75
+ protected boolean mScrollEnable = true;
76
+
77
+ protected boolean mExposureEventEnable = false;
78
+
79
+ private float touchDownY;
80
+ private float touchDownX;
81
+ private int touchSlop;
82
+ private int initialContentOffset = 0;
83
+ private boolean hasCompleteFirstBatch = false;
84
+
85
+ protected int mScrollEventThrottle = 400; // 400ms最多回调一次
86
+ protected int mLastOffsetX = Integer.MIN_VALUE;
87
+ protected int mLastOffsetY = Integer.MIN_VALUE;
88
+ protected long mLastScrollEventTimeStamp = -1;
89
+
90
+ private boolean mHasRemovePreDraw = false;
91
+ private ViewTreeObserver.OnPreDrawListener mPreDrawListener = null;
92
+ private ViewTreeObserver mViewTreeObserver = null;
93
+ private OnInitialListReadyEvent mOnInitialListReadyEvent;
94
+
95
+ private OnScrollDragStartedEvent mOnScrollDragStartedEvent;
96
+ private OnScrollDragEndedEvent mOnScrollDragEndedEvent;
97
+ private OnScrollFlingStartedEvent mOnScrollFlingStartedEvent;
98
+ private OnScrollFlingEndedEvent mOnScrollFlingEndedEvent;
99
+ private OnScrollEvent mOnScrollEvent;
100
+
101
+ //zhaopeng add
102
+ public static final int LOAD_MORE_STATE_LOADING = 1;
103
+ public static final int LOAD_MORE_STATE_IDLE = 0;
104
+ public static final int LOAD_MORE_STATE_DONE = 2;
105
+ private HippyViewEvent mOnScrollStateChanged;
106
+
107
+ protected boolean listShakeSelf;//焦点抖动开关
108
+
109
+ private void init(Context context, int orientation) {
110
+ mHippyContext = ((HippyInstanceContext) context).getEngineContext();
111
+ this.setLayoutManager(onCreateLayoutManager(context, orientation, false));
112
+ setRepeatableSuspensionMode(false);
113
+ mListAdapter = createAdapter(this, mHippyContext);
114
+ setAdapter(mListAdapter);
115
+ listShakeSelf = mHippyContext.getGlobalConfigs().getEsBaseConfigManager().IsListShakeSelf();
116
+ final ViewConfiguration configuration = ViewConfiguration.get(context);
117
+ touchSlop = configuration.getScaledTouchSlop();
118
+ }
119
+
120
+ public HippyListView(Context context, int orientation) {
121
+ super(context);
122
+ init(context, orientation);
123
+ }
124
+
125
+ public HippyListView(Context context) {
126
+ super(context);
127
+ init(context, BaseLayoutManager.VERTICAL);
128
+ }
129
+
130
+ protected HippyListAdapter createAdapter(RecyclerView hippyRecyclerView,
131
+ HippyEngineContext hippyEngineContext) {
132
+ return new HippyListAdapter(hippyRecyclerView, hippyEngineContext);
133
+ }
134
+
135
+ @Override
136
+ public NativeGestureDispatcher getGestureDispatcher() {
137
+ return mGestureDispatcher;
138
+ }
139
+
140
+ @Override
141
+ public void setGestureDispatcher(NativeGestureDispatcher dispatcher) {
142
+ this.mGestureDispatcher = dispatcher;
143
+ }
144
+
145
+ @Override
146
+ public boolean onTouchEvent(MotionEvent motionEvent) {
147
+ if (!mScrollEnable) {
148
+ return false;
149
+ }
150
+ return super.onTouchEvent(motionEvent);
151
+ }
152
+
153
+ @Override
154
+ public boolean onInterceptTouchEvent(MotionEvent motionEvent) {
155
+ if (!mScrollEnable) {
156
+ return false;
157
+ }
158
+
159
+ if (mLayout.canScrollVertically()) {
160
+ int action = motionEvent.getAction();
161
+ float y = motionEvent.getY();
162
+ float x = motionEvent.getX();
163
+ switch (action) {
164
+ case MotionEvent.ACTION_DOWN: {
165
+ touchDownY = y;
166
+ touchDownX = x;
167
+ break;
168
+ }
169
+ case MotionEvent.ACTION_MOVE: {
170
+ if (Math.abs(x - touchDownX) / Math.abs(y - touchDownY) > 1 && Math.abs(x - touchDownX) > touchSlop) {
171
+ return false;
172
+ }
173
+ break;
174
+ }
175
+ }
176
+ }
177
+
178
+ return super.onInterceptTouchEvent(motionEvent);
179
+ }
180
+
181
+ protected int getScrollToPosition(){
182
+ return -1;
183
+ }
184
+
185
+ public void setListData() {
186
+ LogUtils.d("hippylistview", "setListData");
187
+ if(getScrollToPosition() > -1){
188
+ //scrollToIndex(0,getScrollToPosition(),false,0,0);
189
+ scrollToPositionBeforeSetListData();
190
+ }
191
+ mListAdapter.notifyDataSetChanged();
192
+ dispatchLayout();
193
+ if (!hasCompleteFirstBatch && getChildCount() > 0) {
194
+ if (initialContentOffset > 0) {
195
+ scrollToInitContentOffset();
196
+ }
197
+
198
+ hasCompleteFirstBatch = true;
199
+ }
200
+ }
201
+
202
+ protected void scrollToPositionBeforeSetListData(){
203
+
204
+ }
205
+
206
+
207
+ protected HippyListAdapter getListAdapter(){
208
+ return mListAdapter;
209
+ }
210
+
211
+ private void scrollToInitContentOffset() {
212
+ int position = 0;
213
+ int itemHeight = 0;
214
+ if (mListAdapter == null) {
215
+ return;
216
+ }
217
+
218
+ int itemCount = mListAdapter.getItemCount();
219
+ for (; itemHeight < initialContentOffset && position < itemCount; position++) {
220
+ itemHeight += mListAdapter.getItemHeight(position);
221
+ }
222
+
223
+ final int lastIndex = itemCount - 1;
224
+ int offset = itemHeight - initialContentOffset;
225
+
226
+ //设置的offset超过边界,跳转到最后一个Item上去
227
+ if (position >= lastIndex) {
228
+ position = lastIndex;
229
+ //不能划出内容高度
230
+ if (offset < 0) {
231
+ offset = 0;
232
+ }
233
+ }
234
+
235
+ scrollToPosition(position, offset);
236
+ }
237
+
238
+ public void setInitialContentOffset(int offset) {
239
+ initialContentOffset = offset;
240
+ }
241
+
242
+ public void setScrollBeginDragEventEnable(boolean enable) {
243
+ mScrollBeginDragEventEnable = enable;
244
+ }
245
+
246
+ public void setScrollEndDragEventEnable(boolean enable) {
247
+ mScrollEndDragEventEnable = enable;
248
+ }
249
+
250
+ public void setMomentumScrollBeginEventEnable(boolean enable) {
251
+ mMomentumScrollBeginEventEnable = enable;
252
+ }
253
+
254
+ public void setMomentumScrollEndEventEnable(boolean enable) {
255
+ mMomentumScrollEndEventEnable = enable;
256
+ }
257
+
258
+ public void setOnScrollEventEnable(boolean enable) {
259
+ mScrollEventEnable = enable;
260
+ }
261
+
262
+ protected HippyMap generateScrollEvent() {
263
+ float value;
264
+ HippyMap contentOffset = new HippyMap();
265
+ if (mLayout.canScrollHorizontally()) {
266
+ value = (mOffsetX - mState.mCustomHeaderWidth);
267
+ contentOffset.pushDouble("x", value);
268
+ contentOffset.pushDouble("y", 0.0f);
269
+ } else {
270
+ value = (mOffsetY - mState.mCustomHeaderHeight);
271
+ contentOffset.pushDouble("x", 0.0f);
272
+ contentOffset.pushDouble("y", value);
273
+ }
274
+
275
+ HippyMap event = new HippyMap();
276
+ event.pushMap("contentOffset", contentOffset);
277
+ return event;
278
+ }
279
+
280
+ public void setScrollEnable(boolean enable) {
281
+ mScrollEnable = enable;
282
+ }
283
+
284
+ public void setExposureEventEnable(boolean enable) {
285
+ mExposureEventEnable = enable;
286
+ }
287
+
288
+ public void setScrollEventThrottle(int scrollEventThrottle) {
289
+ mScrollEventThrottle = scrollEventThrottle;
290
+ }
291
+
292
+ public View getCustomHeaderView() {
293
+ if (getChildCount() > 0) {
294
+ View firstChild = getChildAt(0);
295
+ final ViewHolder holder = getChildViewHolderInt(firstChild);
296
+ if (holder != null) {
297
+ return holder.mContent;
298
+ }
299
+ }
300
+
301
+ return null;
302
+ }
303
+
304
+ public View getCustomFooterView() {
305
+ if (getChildCount() > 0) {
306
+ View lastChild = getChildAt(getChildCount() - 1);
307
+ final ViewHolder holder = getChildViewHolderInt(lastChild);
308
+ if (holder != null) {
309
+ return holder.mContent;
310
+ }
311
+ }
312
+
313
+ return null;
314
+ }
315
+
316
+ public void onHeaderRefreshFinish() {
317
+ if (mHeaderRefreshState == REFRESH_STATE_LOADING) {
318
+ if (mLayout.canScrollHorizontally()) {
319
+ if (mOffsetX < mState.mCustomHeaderWidth) {
320
+ smoothScrollBy(-mOffsetX + mState.mCustomHeaderWidth, 0, false, true);
321
+ }
322
+ } else {
323
+ if (mOffsetY < mState.mCustomHeaderHeight) {
324
+ smoothScrollBy(0, -mOffsetY + mState.mCustomHeaderHeight, false, true);
325
+ }
326
+ }
327
+
328
+ mHeaderRefreshState = REFRESH_STATE_IDLE;
329
+ }
330
+ }
331
+
332
+ public void onFooterRefreshFinish() {
333
+ if (mFooterRefreshState == REFRESH_STATE_LOADING) {
334
+ if (mLayout.canScrollHorizontally()) {
335
+ int contentOffsetX = getTotalHeight() - getWidth();
336
+ if (mOffsetX > contentOffsetX) {
337
+ smoothScrollBy(contentOffsetX - mOffsetX, 0, false, true);
338
+ }
339
+ } else {
340
+ int contentOffsetY = getTotalHeight() - getHeight();
341
+ if (mOffsetY > contentOffsetY) {
342
+ smoothScrollBy(0, contentOffsetY - mOffsetY, false, true);
343
+ }
344
+ }
345
+ mFooterRefreshState = REFRESH_STATE_IDLE;
346
+ }
347
+ }
348
+
349
+ protected HippyEngineContext getHippyContext(){
350
+ return mHippyContext;
351
+ }
352
+ protected LinearLayoutManager onCreateLayoutManager(Context context,int orientation,boolean reverseLayout){
353
+ return new LinearLayoutManager(context,orientation,reverseLayout);
354
+ }
355
+
356
+ public void onHeaderRefresh() {
357
+ if (mHeaderRefreshState == REFRESH_STATE_IDLE) {
358
+ if (mLayout.canScrollHorizontally()) {
359
+ smoothScrollBy(-mOffsetX, 0, false, true);
360
+ } else {
361
+ smoothScrollBy(0, -mOffsetY, false, true);
362
+ }
363
+ }
364
+ }
365
+
366
+ protected void onTouchMove(int x, int y) {
367
+ int totalHeight = mAdapter.getTotalHeight();
368
+ HippyMap param = new HippyMap();
369
+ float contentOffset = 0;
370
+ String eventName = "";
371
+
372
+ if (mLayout.canScrollHorizontally()) {
373
+ if (mOffsetX < mState.mCustomHeaderWidth) {
374
+ contentOffset = Math.abs((mOffsetX - mState.mCustomHeaderWidth));
375
+ eventName = EVENT_TYPE_HEADER_PULLING;
376
+ } else if (mOffsetX > totalHeight - getWidth()) {
377
+ contentOffset = Math.abs((mOffsetX - totalHeight - getWidth()));
378
+ eventName = EVENT_TYPE_FOOTER_PULLING;
379
+ }
380
+ } else {
381
+ if (getOffsetY() < mState.mCustomHeaderHeight) {
382
+ contentOffset = Math.abs((getOffsetY() - mState.mCustomHeaderHeight));
383
+ eventName = EVENT_TYPE_HEADER_PULLING;
384
+ } else if (getOffsetY() > totalHeight - getHeight()) {
385
+ contentOffset = Math.abs((getOffsetY() - totalHeight - getHeight()));
386
+ eventName = EVENT_TYPE_FOOTER_PULLING;
387
+ }
388
+ }
389
+
390
+ param.pushDouble("contentOffset", PixelUtil.px2dp(contentOffset));
391
+ switch (eventName) {
392
+ case EVENT_TYPE_HEADER_PULLING:
393
+ sendPullHeaderEvent(eventName, param);
394
+ break;
395
+ case EVENT_TYPE_FOOTER_PULLING:
396
+ sendPullFooterEvent(eventName, param);
397
+ break;
398
+ }
399
+ }
400
+
401
+ private boolean shouldStopReleaseGlowsForHorizontal(boolean fromTouch) {
402
+ int totalHeight = mAdapter.getTotalHeight();
403
+ if (mOffsetX <= 0 || getWidth() > (totalHeight - mState.mCustomHeaderWidth)) {
404
+ if (mHeaderRefreshState == REFRESH_STATE_IDLE && fromTouch) {
405
+ sendPullHeaderEvent(EVENT_TYPE_HEADER_RELEASED, new HippyMap());
406
+ mHeaderRefreshState = REFRESH_STATE_LOADING;
407
+ }
408
+
409
+ if (mOffsetX < 0) {
410
+ smoothScrollBy(-mOffsetX, 0, false, true);
411
+ }
412
+ return true;
413
+ } else {
414
+ int refreshEnableOffsetX = totalHeight - getWidth() + mState.mCustomFooterWidth;
415
+ if ((totalHeight - mState.mCustomHeaderWidth) < getWidth()
416
+ || mOffsetX >= refreshEnableOffsetX) {
417
+ if (mFooterRefreshState == REFRESH_STATE_IDLE) {
418
+ sendPullFooterEvent(EVENT_TYPE_FOOTER_RELEASED, new HippyMap());
419
+ mFooterRefreshState = REFRESH_STATE_LOADING;
420
+ }
421
+
422
+ View footerView = getCustomFooterView();
423
+ if (footerView instanceof HippyPullFooterView) {
424
+ boolean stickEnabled = ((HippyPullFooterView) footerView).getStickEnabled();
425
+ if (stickEnabled) {
426
+ smoothScrollBy(refreshEnableOffsetX - mOffsetX, 0, false, true);
427
+ return true;
428
+ }
429
+ }
430
+ }
431
+ }
432
+
433
+ return false;
434
+ }
435
+
436
+ private boolean shouldStopReleaseGlowsForVertical(boolean fromTouch) {
437
+ int totalHeight = mAdapter.getTotalHeight();
438
+ if (getOffsetY() <= 0 || getHeight() > (totalHeight - mState.mCustomHeaderHeight)) {
439
+ if (mHeaderRefreshState == REFRESH_STATE_IDLE && fromTouch) {
440
+ sendPullHeaderEvent(EVENT_TYPE_HEADER_RELEASED, new HippyMap());
441
+ mHeaderRefreshState = REFRESH_STATE_LOADING;
442
+ }
443
+ if (getOffsetY() < 0) {
444
+ smoothScrollBy(0, -mOffsetY, false, true);
445
+ }
446
+ return true;
447
+ } else {
448
+ int refreshEnableOffsetY = totalHeight - getHeight() + mState.mCustomFooterHeight;
449
+ if ((totalHeight - mState.mCustomHeaderHeight) < getHeight()
450
+ || getOffsetY() >= refreshEnableOffsetY) {
451
+ if (mFooterRefreshState == REFRESH_STATE_IDLE) {
452
+ sendPullFooterEvent(EVENT_TYPE_FOOTER_RELEASED, new HippyMap());
453
+ mFooterRefreshState = REFRESH_STATE_LOADING;
454
+ }
455
+
456
+ View footerView = getCustomFooterView();
457
+ if (footerView instanceof HippyPullFooterView) {
458
+ boolean stickEnabled = ((HippyPullFooterView) footerView).getStickEnabled();
459
+ if (stickEnabled) {
460
+ smoothScrollBy(0, refreshEnableOffsetY - mOffsetY, false, true);
461
+ return true;
462
+ }
463
+ }
464
+ }
465
+ }
466
+
467
+ return false;
468
+ }
469
+
470
+ @Override
471
+ protected boolean shouldStopReleaseGlows(boolean canGoRefresh, boolean fromTouch) {
472
+ if (mEnableRefresh) {
473
+ // Scroller scroller = mViewFlinger.getScroller();
474
+ // if (scroller.isFinished() && scroller.isFling() && getOffsetY() < 0) {
475
+ // canGoRefresh = true;
476
+ // }
477
+
478
+ if (!canGoRefresh) {
479
+ return false;
480
+ }
481
+
482
+ if (mLayout.canScrollHorizontally()) {
483
+ return shouldStopReleaseGlowsForHorizontal(fromTouch);
484
+ } else {
485
+ return shouldStopReleaseGlowsForVertical(fromTouch);
486
+ }
487
+ }
488
+
489
+ return false;
490
+ }
491
+
492
+ @Override
493
+ protected void onScrollDragStarted() {
494
+ if (mScrollBeginDragEventEnable) {
495
+ getOnScrollDragStartedEvent().send(this, generateScrollEvent());
496
+ }
497
+ }
498
+
499
+ @Override
500
+ protected void onScrollDragEnded() {
501
+ if (mScrollEndDragEventEnable) {
502
+ getOnScrollDragEndedEvent().send(this, generateScrollEvent());
503
+ }
504
+ }
505
+
506
+ @Override
507
+ protected void onScrollFlingStarted() {
508
+ if (mMomentumScrollBeginEventEnable) {
509
+ getOnScrollFlingStartedEvent().send(this, generateScrollEvent());
510
+ }
511
+ }
512
+
513
+ @Override
514
+ protected void onScrollFlingEnded() {
515
+ if (mMomentumScrollEndEventEnable) {
516
+ getOnScrollFlingEndedEvent().send(this, generateScrollEvent());
517
+ }
518
+ }
519
+
520
+ @Override
521
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
522
+ super.onLayout(changed, l, t, r, b);
523
+ if (changed && mExposureEventEnable) {
524
+ dispatchExposureEvent();
525
+ }
526
+ }
527
+
528
+ @Override
529
+ public void onScrollStateChanged(int oldState, int newState) {
530
+ super.onScrollStateChanged(oldState, newState);
531
+ HippyMap stateMap = new HippyMap();
532
+ stateMap.pushInt("oldState",oldState);
533
+ stateMap.pushInt("newState",newState);
534
+ HippyMap contentOffset = new HippyMap();
535
+ contentOffset.pushDouble("x", PixelUtil.px2dp(getOffsetX()));
536
+ contentOffset.pushDouble("y", PixelUtil.px2dp(getOffsetY()));
537
+ HippyMap map = new HippyMap();
538
+ map.pushMap("state",stateMap);
539
+ map.pushMap("contentOffset",contentOffset);
540
+ getOnScrollStateChanged().send(this,map);
541
+ }
542
+
543
+ @Override
544
+ public void onScrolled(int x, int y) {
545
+ super.onScrolled(x, y);
546
+
547
+ sendOnScrollEvent();
548
+ if (mExposureEventEnable) {
549
+ dispatchExposureEvent();
550
+ }
551
+ }
552
+
553
+
554
+ protected void sendExposureEvent(View view, String eventName, HippyMap props) {
555
+ if (props.containsKey(eventName)) {
556
+ new HippyViewEvent(eventName).send(view, null);
557
+ }
558
+ }
559
+
560
+ private HippyMap getItemViewProps(int id) {
561
+ if (mHippyContext == null) {
562
+ return null;
563
+ }
564
+ RenderNode node = mHippyContext.getRenderManager().getRenderNode(id);
565
+ if (node == null) {
566
+ return null;
567
+ }
568
+
569
+ return node.getProps();
570
+ }
571
+
572
+ protected void checkExposureView(View view, int visibleStart, int visibleEnd, int parentStart,
573
+ int parentEnd) {
574
+ if (!(view instanceof HippyListItemView)) {
575
+ return;
576
+ }
577
+
578
+ int myStart = (mLayout.canScrollHorizontally()) ? view.getLeft() : view.getTop();
579
+ int myEnd = (mLayout.canScrollHorizontally()) ? view.getRight() : view.getBottom();
580
+ myStart += parentStart;
581
+ myEnd += parentStart;
582
+
583
+ HippyListItemView itemView = (HippyListItemView) view;
584
+ HippyMap props = getItemViewProps(itemView.getId());
585
+ if (props == null) {
586
+ return;
587
+ }
588
+
589
+ int currentExposureState = itemView.getExposureState();
590
+ int viewSize = (mLayout.canScrollHorizontally()) ? view.getWidth() : view.getHeight();
591
+ int correctingValueForDisappear = (int) Math.ceil(viewSize * 0.1f);
592
+
593
+ if (myEnd <= (visibleStart + correctingValueForDisappear) || myStart >= (visibleEnd
594
+ - correctingValueForDisappear)) {
595
+ if (itemView.getExposureState() != HippyListItemView.EXPOSURE_STATE_DISAPPEAR) {
596
+ if (itemView.getExposureState() == HippyListItemView.EXPOSURE_STATE_APPEAR) {
597
+ sendExposureEvent(view, HippyListItemView.EXPOSURE_EVENT_WILL_DISAPPEAR, props);
598
+ }
599
+ sendExposureEvent(view, HippyListItemView.EXPOSURE_EVENT_DISAPPEAR, props);
600
+ itemView.setExposureState(HippyListItemView.EXPOSURE_STATE_DISAPPEAR);
601
+ }
602
+ } else if ((myStart < visibleStart && myEnd > visibleStart) || (myStart < visibleEnd
603
+ && myEnd > visibleEnd)) {
604
+ if (currentExposureState == HippyListItemView.EXPOSURE_STATE_APPEAR) {
605
+ sendExposureEvent(view, HippyListItemView.EXPOSURE_EVENT_WILL_DISAPPEAR, props);
606
+ itemView.setExposureState(HippyListItemView.EXPOSURE_STATE_WILL_DISAPPEAR);
607
+ } else if (currentExposureState == HippyListItemView.EXPOSURE_STATE_DISAPPEAR) {
608
+ sendExposureEvent(view, HippyListItemView.EXPOSURE_EVENT_WILL_APPEAR, props);
609
+ itemView.setExposureState(HippyListItemView.EXPOSURE_STATE_WILL_APPEAR);
610
+ }
611
+ } else if ((myStart >= visibleStart && myEnd <= visibleEnd) || (myStart <= visibleStart
612
+ && myEnd > visibleEnd)) {
613
+ if (itemView.getExposureState() != HippyListItemView.EXPOSURE_STATE_APPEAR) {
614
+ if (itemView.getExposureState() == HippyListItemView.EXPOSURE_STATE_DISAPPEAR) {
615
+ sendExposureEvent(view, HippyListItemView.EXPOSURE_EVENT_WILL_APPEAR, props);
616
+ }
617
+ sendExposureEvent(view, HippyListItemView.EXPOSURE_EVENT_APPEAR, props);
618
+ itemView.setExposureState(HippyListItemView.EXPOSURE_STATE_APPEAR);
619
+ }
620
+ }
621
+ }
622
+
623
+ private void dispatchExposureEvent() {
624
+ if (mLayout instanceof BaseLayoutManager) {
625
+ BaseLayoutManager.OrientationHelper layoutHelper = ((BaseLayoutManager) mLayout).mOrientationHelper;
626
+ int count = getChildCount();
627
+ int fixOffset = (mLayout.canScrollHorizontally()) ? mState.mCustomHeaderWidth
628
+ : mState.mCustomHeaderHeight;
629
+ int start = layoutHelper.getStartAfterPadding() + fixOffset;
630
+ int end = layoutHelper.getEndAfterPadding() - fixOffset;
631
+ for (int i = 0; i < count; i++) {
632
+ final View child = getChildAt(i);
633
+ final int childStart = layoutHelper.getDecoratedStart(child);
634
+ final int childEnd = layoutHelper.getDecoratedEnd(child);
635
+ if (child instanceof RecyclerViewItem) {
636
+ RecyclerViewItem itemView = (RecyclerViewItem) child;
637
+ if (itemView.getChildCount() > 0) {
638
+ checkExposureView(itemView.getChildAt(0), start, end, childStart, childEnd);
639
+ }
640
+ }
641
+ }
642
+ }
643
+ }
644
+
645
+ @Override
646
+ protected void onAttachedToWindow() {
647
+ super.onAttachedToWindow();
648
+ if (!mHasRemovePreDraw) {
649
+ mViewTreeObserver = getViewTreeObserver();
650
+ if (mPreDrawListener == null) {
651
+ mPreDrawListener = new ViewTreeObserver.OnPreDrawListener() {
652
+ @Override
653
+ public boolean onPreDraw() {
654
+ if (mAdapter.getItemCount() > 0 && HippyListView.this.getChildCount() > 0) {
655
+ mViewTreeObserver.removeOnPreDrawListener(this);
656
+ mHasRemovePreDraw = true;
657
+
658
+ post(new Runnable() {
659
+ @Override
660
+ public void run() {
661
+ HippyListView.this.onInitialListReady();
662
+ getOnInitialListReadyEvent().send(HippyListView.this, null);
663
+ }
664
+ });
665
+
666
+ }
667
+ return true;
668
+ }
669
+ };
670
+ }
671
+ mViewTreeObserver.removeOnPreDrawListener(mPreDrawListener);
672
+ mViewTreeObserver.addOnPreDrawListener(mPreDrawListener);
673
+
674
+ }
675
+ }
676
+
677
+ @Override
678
+ protected void onDetachedFromWindow() {
679
+ if (mPreDrawListener != null && mViewTreeObserver != null) {
680
+ mViewTreeObserver.removeOnPreDrawListener(mPreDrawListener);
681
+ }
682
+ super.onDetachedFromWindow();
683
+ }
684
+
685
+ public void scrollToIndex(int xIndex, int yIndex, boolean animated, int duration,int offset) {
686
+ if (animated) {
687
+ int scrollToYPos = getHeightBefore(yIndex) - getOffsetY() + offset;
688
+ if (duration != 0) //如果用户设置了duration
689
+ {
690
+ if (scrollToYPos != 0) {
691
+ if (!mState.didStructureChange()) {
692
+ mViewFlinger.smoothScrollBy(0, scrollToYPos, duration, true);
693
+ }
694
+ }
695
+ } else {
696
+ smoothScrollBy(0, scrollToYPos);
697
+ }
698
+ } else {
699
+ scrollToPosition(yIndex, offset);
700
+ post(new Runnable() {
701
+ @Override
702
+ public void run() {
703
+ dispatchLayout();
704
+ }
705
+ });
706
+ }
707
+ }
708
+
709
+ public void scrollToIndex(int xIndex, int yIndex, boolean animated, int duration) {
710
+ scrollToIndex(xIndex,yIndex,animated,duration,0);
711
+ }
712
+
713
+ public void scrollToContentOffset(double xOffset, double yOffset, boolean animated,
714
+ int duration) {
715
+ int scrollToYPos = (int)PixelUtil.dp2px(yOffset) - mOffsetY;
716
+ int scrollToXPos = (int)PixelUtil.dp2px(xOffset) - mOffsetX;
717
+ if (animated) {
718
+ if (duration != 0){
719
+ if ((scrollToYPos != 0 || scrollToXPos != 0) && !mState.didStructureChange()) {
720
+ mViewFlinger.smoothScrollBy(scrollToXPos, scrollToYPos, duration, true);
721
+ }
722
+ } else {
723
+ smoothScrollBy(scrollToXPos, scrollToYPos);
724
+ }
725
+ } else {
726
+ scrollBy(scrollToXPos, scrollToYPos);
727
+ post(new Runnable() {
728
+ @Override
729
+ public void run() {
730
+ dispatchLayout();
731
+ }
732
+ });
733
+ }
734
+ }
735
+
736
+ protected void sendOnScrollEvent() {
737
+ if (mScrollEventEnable) {
738
+ long currTime = System.currentTimeMillis();
739
+ if (currTime - mLastScrollEventTimeStamp < mScrollEventThrottle) {
740
+ return;
741
+ }
742
+ onSendScrollEvent();
743
+ mLastScrollEventTimeStamp = currTime;
744
+ getOnScrollEvent().send(this, generateScrollEvent());
745
+ }
746
+ }
747
+
748
+ protected void onSendScrollEvent(){
749
+
750
+ }
751
+
752
+ // start drag event
753
+ protected OnScrollDragStartedEvent getOnScrollDragStartedEvent() {
754
+ if (mOnScrollDragStartedEvent == null) {
755
+ mOnScrollDragStartedEvent = new OnScrollDragStartedEvent(
756
+ HippyScrollViewEventHelper.EVENT_TYPE_BEGIN_DRAG);
757
+ }
758
+ return mOnScrollDragStartedEvent;
759
+ }
760
+
761
+ protected static class OnScrollDragStartedEvent extends HippyViewEvent {
762
+
763
+ public OnScrollDragStartedEvent(String eventName) {
764
+ super(eventName);
765
+ }
766
+ }
767
+
768
+ // end drag event
769
+ protected OnScrollDragEndedEvent getOnScrollDragEndedEvent() {
770
+ if (mOnScrollDragEndedEvent == null) {
771
+ mOnScrollDragEndedEvent = new OnScrollDragEndedEvent(
772
+ HippyScrollViewEventHelper.EVENT_TYPE_END_DRAG);
773
+ }
774
+ return mOnScrollDragEndedEvent;
775
+ }
776
+
777
+ protected static class OnScrollDragEndedEvent extends HippyViewEvent {
778
+
779
+ public OnScrollDragEndedEvent(String eventName) {
780
+ super(eventName);
781
+ }
782
+ }
783
+
784
+ // start fling
785
+ protected OnScrollFlingStartedEvent getOnScrollFlingStartedEvent() {
786
+ if (mOnScrollFlingStartedEvent == null) {
787
+ mOnScrollFlingStartedEvent = new OnScrollFlingStartedEvent(
788
+ HippyScrollViewEventHelper.EVENT_TYPE_MOMENTUM_BEGIN);
789
+ }
790
+ return mOnScrollFlingStartedEvent;
791
+ }
792
+
793
+ protected static class OnScrollFlingStartedEvent extends HippyViewEvent {
794
+
795
+ public OnScrollFlingStartedEvent(String eventName) {
796
+ super(eventName);
797
+ }
798
+ }
799
+
800
+ // end fling
801
+ protected OnScrollFlingEndedEvent getOnScrollFlingEndedEvent() {
802
+ if (mOnScrollFlingEndedEvent == null) {
803
+ mOnScrollFlingEndedEvent = new OnScrollFlingEndedEvent(
804
+ HippyScrollViewEventHelper.EVENT_TYPE_MOMENTUM_END);
805
+ }
806
+ return mOnScrollFlingEndedEvent;
807
+ }
808
+
809
+ protected static class OnScrollFlingEndedEvent extends HippyViewEvent {
810
+
811
+ public OnScrollFlingEndedEvent(String eventName) {
812
+ super(eventName);
813
+ }
814
+ }
815
+
816
+ // scroll
817
+ protected OnScrollEvent getOnScrollEvent() {
818
+ if (mOnScrollEvent == null) {
819
+ mOnScrollEvent = new OnScrollEvent(HippyScrollViewEventHelper.EVENT_TYPE_SCROLL);
820
+ }
821
+ return mOnScrollEvent;
822
+ }
823
+
824
+ protected static class OnScrollEvent extends HippyViewEvent {
825
+
826
+ public OnScrollEvent(String eventName) {
827
+ super(eventName);
828
+ }
829
+ }
830
+
831
+ private OnInitialListReadyEvent getOnInitialListReadyEvent() {
832
+ if (mOnInitialListReadyEvent == null) {
833
+ mOnInitialListReadyEvent = new OnInitialListReadyEvent("initialListReady");
834
+ }
835
+ return mOnInitialListReadyEvent;
836
+ }
837
+
838
+ private static class OnInitialListReadyEvent extends HippyViewEvent {
839
+
840
+ public OnInitialListReadyEvent(String eventName) {
841
+ super(eventName);
842
+ }
843
+ }
844
+
845
+ @SuppressWarnings("EmptyMethod")
846
+ protected void onInitialListReady() {
847
+
848
+ }
849
+
850
+ protected static class PullElementEvent extends HippyViewEvent {
851
+
852
+ public PullElementEvent(String eventName) {
853
+ super(eventName);
854
+ }
855
+ }
856
+
857
+ protected void sendPullHeaderEvent(String eventName, HippyMap param) {
858
+ PullElementEvent event = new PullElementEvent(eventName);
859
+ View headerView = getCustomHeaderView();
860
+ if (headerView instanceof HippyPullHeaderView) {
861
+ event.send(headerView, param);
862
+ }
863
+ }
864
+
865
+ protected void sendPullFooterEvent(String eventName, HippyMap param) {
866
+ PullElementEvent event = new PullElementEvent(eventName);
867
+ View footerView = getCustomFooterView();
868
+ if (footerView instanceof HippyPullFooterView) {
869
+ event.send(footerView, param);
870
+ }
871
+ }
872
+
873
+ /*** add by zhaopeng ***/
874
+ private boolean mBringToFrontOnFocus = true;
875
+
876
+ public void setBringToFrontOnFocus(boolean mBringToFrontOnFocus) {
877
+ this.mBringToFrontOnFocus = mBringToFrontOnFocus;
878
+ postInvalidateDelayed(16);
879
+ }
880
+
881
+ @Override
882
+ protected void dispatchDraw(Canvas canvas) {
883
+ super.dispatchDraw(canvas);
884
+ if(mBringToFrontOnFocus && getFocusedChild() != null)
885
+ super.drawChild(canvas,getFocusedChild(),getDrawingTime());
886
+ }
887
+
888
+ @Override
889
+ public boolean drawChild(Canvas canvas, View child, long drawingTime) {
890
+ if(mBringToFrontOnFocus && child == getFocusedChild())
891
+ return true;
892
+ return super.drawChild(canvas, child, drawingTime);
893
+ }
894
+
895
+ @Override
896
+ public void requestChildFocus(View child, View focused) {
897
+ super.requestChildFocus(child, focused);
898
+ //for focusScale
899
+ postInvalidateDelayed(16);
900
+ }
901
+
902
+ protected HippyViewEvent getOnScrollStateChanged()
903
+ {
904
+ if (mOnScrollStateChanged == null)
905
+ {
906
+ mOnScrollStateChanged = new HippyViewEvent("onScrollStateChanged");
907
+ }
908
+ return mOnScrollStateChanged;
909
+ }
910
+
911
+ public void setListShakeSelf(boolean shakeSelf) {
912
+ this.listShakeSelf = shakeSelf;
913
+ }
914
+
915
+ }