@nativescript/core 9.0.0-alpha.24 → 9.0.0-alpha.26

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 (267) hide show
  1. package/application/application-common.d.ts +29 -10
  2. package/application/application-common.js +58 -5
  3. package/application/application-common.js.map +1 -1
  4. package/application/application-interfaces.d.ts +10 -0
  5. package/application/application-shims.d.ts +27 -0
  6. package/application/application-shims.js +27 -0
  7. package/application/application-shims.js.map +1 -1
  8. package/application/application.android.d.ts +12 -2
  9. package/application/application.android.js +418 -342
  10. package/application/application.android.js.map +1 -1
  11. package/application/application.d.ts +8 -1
  12. package/application/application.ios.d.ts +16 -1
  13. package/application/application.ios.js +59 -21
  14. package/application/application.ios.js.map +1 -1
  15. package/application/helpers.android.d.ts +0 -9
  16. package/application/helpers.android.js +0 -54
  17. package/application/helpers.android.js.map +1 -1
  18. package/application/helpers.d.ts +0 -10
  19. package/application/helpers.ios.d.ts +0 -19
  20. package/application/helpers.ios.js +0 -38
  21. package/application/helpers.ios.js.map +1 -1
  22. package/config/config.interface.d.ts +21 -0
  23. package/connectivity/index.android.js +25 -25
  24. package/connectivity/index.android.js.map +1 -1
  25. package/core-types/index.d.ts +77 -63
  26. package/core-types/index.js +10 -1
  27. package/core-types/index.js.map +1 -1
  28. package/core-types/validators.js +12 -6
  29. package/core-types/validators.js.map +1 -1
  30. package/data/observable/index.d.ts +2 -1
  31. package/data/observable/index.js +31 -19
  32. package/data/observable/index.js.map +1 -1
  33. package/fps-meter/fps-native.ios.js +1 -1
  34. package/fps-meter/fps-native.ios.js.map +1 -1
  35. package/http/http-request/index.ios.js +1 -1
  36. package/http/http-request/index.ios.js.map +1 -1
  37. package/image-source/index.d.ts +2 -2
  38. package/index.js +0 -1
  39. package/index.js.map +1 -1
  40. package/package.json +1 -1
  41. package/platform/screen/index.d.ts +5 -0
  42. package/platforms/android/widgets-release.aar +0 -0
  43. package/references.d.ts +1 -1
  44. package/timer/index.ios.js +1 -1
  45. package/timer/index.ios.js.map +1 -1
  46. package/ui/action-bar/index.android.js +18 -18
  47. package/ui/action-bar/index.android.js.map +1 -1
  48. package/ui/action-bar/index.ios.js +2 -4
  49. package/ui/action-bar/index.ios.js.map +1 -1
  50. package/ui/animation/index.ios.js +2 -3
  51. package/ui/animation/index.ios.js.map +1 -1
  52. package/ui/button/index.android.js +20 -20
  53. package/ui/button/index.android.js.map +1 -1
  54. package/ui/button/index.ios.d.ts +2 -1
  55. package/ui/button/index.ios.js +28 -10
  56. package/ui/button/index.ios.js.map +1 -1
  57. package/ui/core/control-state-change/index.ios.js +1 -1
  58. package/ui/core/control-state-change/index.ios.js.map +1 -1
  59. package/ui/core/view/index.android.d.ts +6 -6
  60. package/ui/core/view/index.android.js +337 -455
  61. package/ui/core/view/index.android.js.map +1 -1
  62. package/ui/core/view/index.d.ts +18 -5
  63. package/ui/core/view/index.ios.d.ts +10 -2
  64. package/ui/core/view/index.ios.js +99 -46
  65. package/ui/core/view/index.ios.js.map +1 -1
  66. package/ui/core/view/view-common.d.ts +46 -12
  67. package/ui/core/view/view-common.js +28 -0
  68. package/ui/core/view/view-common.js.map +1 -1
  69. package/ui/core/view/view-helper/index.d.ts +5 -0
  70. package/ui/core/view/view-helper/index.ios.d.ts +5 -4
  71. package/ui/core/view/view-helper/index.ios.js +20 -23
  72. package/ui/core/view/view-helper/index.ios.js.map +1 -1
  73. package/ui/core/view/view-helper/view-helper-common.js +7 -0
  74. package/ui/core/view/view-helper/view-helper-common.js.map +1 -1
  75. package/ui/core/view/view-interfaces.d.ts +3 -0
  76. package/ui/core/view-base/index.d.ts +4 -0
  77. package/ui/core/view-base/index.js +4 -0
  78. package/ui/core/view-base/index.js.map +1 -1
  79. package/ui/date-picker/index.android.js +38 -38
  80. package/ui/date-picker/index.android.js.map +1 -1
  81. package/ui/date-picker/index.ios.js +1 -1
  82. package/ui/date-picker/index.ios.js.map +1 -1
  83. package/ui/editable-text-base/index.android.js +34 -34
  84. package/ui/editable-text-base/index.android.js.map +1 -1
  85. package/ui/frame/fragment.transitions.android.d.ts +2 -1
  86. package/ui/frame/fragment.transitions.android.js +106 -104
  87. package/ui/frame/fragment.transitions.android.js.map +1 -1
  88. package/ui/frame/fragment.transitions.d.ts +3 -2
  89. package/ui/frame/index.android.js +57 -4
  90. package/ui/frame/index.android.js.map +1 -1
  91. package/ui/frame/index.ios.d.ts +2 -1
  92. package/ui/frame/index.ios.js +83 -43
  93. package/ui/frame/index.ios.js.map +1 -1
  94. package/ui/gestures/index.android.js +129 -130
  95. package/ui/gestures/index.android.js.map +1 -1
  96. package/ui/gestures/index.ios.js +3 -5
  97. package/ui/gestures/index.ios.js.map +1 -1
  98. package/ui/gestures/touch-manager.js +32 -32
  99. package/ui/gestures/touch-manager.js.map +1 -1
  100. package/ui/image/index.android.js +19 -19
  101. package/ui/image/index.android.js.map +1 -1
  102. package/ui/image-cache/index.android.js +12 -14
  103. package/ui/image-cache/index.android.js.map +1 -1
  104. package/ui/image-cache/index.ios.js +6 -6
  105. package/ui/image-cache/index.ios.js.map +1 -1
  106. package/ui/index.d.ts +2 -1
  107. package/ui/index.js +1 -0
  108. package/ui/index.js.map +1 -1
  109. package/ui/label/index.android.js +4 -1
  110. package/ui/label/index.android.js.map +1 -1
  111. package/ui/label/index.ios.d.ts +2 -1
  112. package/ui/label/index.ios.js +12 -2
  113. package/ui/label/index.ios.js.map +1 -1
  114. package/ui/layouts/flexbox-layout/index.ios.js +3 -6
  115. package/ui/layouts/flexbox-layout/index.ios.js.map +1 -1
  116. package/ui/layouts/index.d.ts +2 -0
  117. package/ui/layouts/index.js +2 -0
  118. package/ui/layouts/index.js.map +1 -1
  119. package/ui/layouts/liquid-glass/index.android.d.ts +5 -0
  120. package/ui/layouts/liquid-glass/index.android.js +8 -0
  121. package/ui/layouts/liquid-glass/index.android.js.map +1 -0
  122. package/ui/layouts/liquid-glass/index.d.ts +10 -0
  123. package/ui/layouts/liquid-glass/index.ios.d.ts +10 -0
  124. package/ui/layouts/liquid-glass/index.ios.js +59 -0
  125. package/ui/layouts/liquid-glass/index.ios.js.map +1 -0
  126. package/ui/layouts/liquid-glass/liquid-glass-common.d.ts +3 -0
  127. package/ui/layouts/liquid-glass/liquid-glass-common.js +4 -0
  128. package/ui/layouts/liquid-glass/liquid-glass-common.js.map +1 -0
  129. package/ui/layouts/liquid-glass-container/index.android.d.ts +3 -0
  130. package/ui/layouts/liquid-glass-container/index.android.js +4 -0
  131. package/ui/layouts/liquid-glass-container/index.android.js.map +1 -0
  132. package/ui/layouts/liquid-glass-container/index.d.ts +3 -0
  133. package/ui/layouts/liquid-glass-container/index.ios.d.ts +14 -0
  134. package/ui/layouts/liquid-glass-container/index.ios.js +121 -0
  135. package/ui/layouts/liquid-glass-container/index.ios.js.map +1 -0
  136. package/ui/layouts/liquid-glass-container/liquid-glass-container-common.d.ts +4 -0
  137. package/ui/layouts/liquid-glass-container/liquid-glass-container-common.js +5 -0
  138. package/ui/layouts/liquid-glass-container/liquid-glass-container-common.js.map +1 -0
  139. package/ui/layouts/stack-layout/index.ios.js +6 -0
  140. package/ui/layouts/stack-layout/index.ios.js.map +1 -1
  141. package/ui/list-picker/index.android.js +35 -35
  142. package/ui/list-picker/index.android.js.map +1 -1
  143. package/ui/list-picker/index.ios.js +2 -2
  144. package/ui/list-picker/index.ios.js.map +1 -1
  145. package/ui/list-view/index.android.d.ts +26 -1
  146. package/ui/list-view/index.android.js +765 -129
  147. package/ui/list-view/index.android.js.map +1 -1
  148. package/ui/list-view/index.d.ts +127 -0
  149. package/ui/list-view/index.ios.d.ts +34 -2
  150. package/ui/list-view/index.ios.js +557 -21
  151. package/ui/list-view/index.ios.js.map +1 -1
  152. package/ui/list-view/list-view-common.d.ts +22 -1
  153. package/ui/list-view/list-view-common.js +85 -0
  154. package/ui/list-view/list-view-common.js.map +1 -1
  155. package/ui/page/index.ios.js +25 -64
  156. package/ui/page/index.ios.js.map +1 -1
  157. package/ui/scroll-view/index.d.ts +1 -1
  158. package/ui/scroll-view/index.ios.d.ts +2 -0
  159. package/ui/scroll-view/index.ios.js +31 -12
  160. package/ui/scroll-view/index.ios.js.map +1 -1
  161. package/ui/scroll-view/scroll-view-common.d.ts +3 -8
  162. package/ui/scroll-view/scroll-view-common.js +4 -4
  163. package/ui/scroll-view/scroll-view-common.js.map +1 -1
  164. package/ui/search-bar/index.android.js +48 -52
  165. package/ui/search-bar/index.android.js.map +1 -1
  166. package/ui/search-bar/index.ios.js +3 -6
  167. package/ui/search-bar/index.ios.js.map +1 -1
  168. package/ui/segmented-bar/index.android.js +56 -58
  169. package/ui/segmented-bar/index.android.js.map +1 -1
  170. package/ui/segmented-bar/index.ios.js +1 -1
  171. package/ui/segmented-bar/index.ios.js.map +1 -1
  172. package/ui/slider/index.android.js +23 -25
  173. package/ui/slider/index.android.js.map +1 -1
  174. package/ui/slider/index.ios.js +2 -2
  175. package/ui/slider/index.ios.js.map +1 -1
  176. package/ui/split-view/index.android.d.ts +4 -0
  177. package/ui/split-view/index.android.js +4 -0
  178. package/ui/split-view/index.android.js.map +1 -0
  179. package/ui/split-view/index.d.ts +11 -0
  180. package/ui/split-view/index.ios.d.ts +39 -0
  181. package/ui/split-view/index.ios.js +368 -0
  182. package/ui/split-view/index.ios.js.map +1 -0
  183. package/ui/split-view/split-view-common.d.ts +51 -0
  184. package/ui/split-view/split-view-common.js +111 -0
  185. package/ui/split-view/split-view-common.js.map +1 -0
  186. package/ui/styling/background-common.d.ts +4 -4
  187. package/ui/styling/background-common.js +8 -8
  188. package/ui/styling/background-common.js.map +1 -1
  189. package/ui/styling/background.d.ts +0 -3
  190. package/ui/styling/background.ios.d.ts +2 -1
  191. package/ui/styling/background.ios.js +47 -38
  192. package/ui/styling/background.ios.js.map +1 -1
  193. package/ui/styling/css-utils.d.ts +1 -0
  194. package/ui/styling/css-utils.js +15 -4
  195. package/ui/styling/css-utils.js.map +1 -1
  196. package/ui/styling/style/index.d.ts +3 -1
  197. package/ui/styling/style/index.js.map +1 -1
  198. package/ui/styling/style-properties.d.ts +1 -0
  199. package/ui/styling/style-properties.js +30 -11
  200. package/ui/styling/style-properties.js.map +1 -1
  201. package/ui/switch/index.android.js +18 -18
  202. package/ui/switch/index.android.js.map +1 -1
  203. package/ui/switch/index.ios.d.ts +1 -0
  204. package/ui/switch/index.ios.js +62 -12
  205. package/ui/switch/index.ios.js.map +1 -1
  206. package/ui/tab-view/index.android.js +185 -187
  207. package/ui/tab-view/index.android.js.map +1 -1
  208. package/ui/tab-view/index.d.ts +17 -1
  209. package/ui/tab-view/index.ios.d.ts +13 -5
  210. package/ui/tab-view/index.ios.js +253 -49
  211. package/ui/tab-view/index.ios.js.map +1 -1
  212. package/ui/tab-view/tab-view-common.d.ts +14 -0
  213. package/ui/tab-view/tab-view-common.js +15 -0
  214. package/ui/tab-view/tab-view-common.js.map +1 -1
  215. package/ui/text-base/index.android.d.ts +2 -1
  216. package/ui/text-base/index.android.js +133 -101
  217. package/ui/text-base/index.android.js.map +1 -1
  218. package/ui/text-base/index.d.ts +5 -0
  219. package/ui/text-base/index.ios.js +12 -18
  220. package/ui/text-base/index.ios.js.map +1 -1
  221. package/ui/text-base/text-base-common.d.ts +2 -1
  222. package/ui/text-base/text-base-common.js +1 -0
  223. package/ui/text-base/text-base-common.js.map +1 -1
  224. package/ui/text-field/index.ios.d.ts +2 -1
  225. package/ui/text-field/index.ios.js +9 -5
  226. package/ui/text-field/index.ios.js.map +1 -1
  227. package/ui/text-view/index.ios.d.ts +2 -1
  228. package/ui/text-view/index.ios.js +12 -7
  229. package/ui/text-view/index.ios.js.map +1 -1
  230. package/ui/time-picker/index.android.js +21 -21
  231. package/ui/time-picker/index.android.js.map +1 -1
  232. package/ui/time-picker/index.ios.js +1 -1
  233. package/ui/time-picker/index.ios.js.map +1 -1
  234. package/ui/transition/fade-transition.ios.js +5 -6
  235. package/ui/transition/fade-transition.ios.js.map +1 -1
  236. package/ui/transition/modal-transition.ios.js +19 -26
  237. package/ui/transition/modal-transition.ios.js.map +1 -1
  238. package/ui/transition/page-transition.android.js +3 -12
  239. package/ui/transition/page-transition.android.js.map +1 -1
  240. package/ui/transition/page-transition.ios.js +19 -25
  241. package/ui/transition/page-transition.ios.js.map +1 -1
  242. package/ui/transition/slide-transition.ios.js +5 -6
  243. package/ui/transition/slide-transition.ios.js.map +1 -1
  244. package/ui/web-view/index.android.js +58 -62
  245. package/ui/web-view/index.android.js.map +1 -1
  246. package/ui/web-view/index.ios.js +18 -18
  247. package/ui/web-view/index.ios.js.map +1 -1
  248. package/utils/common.d.ts +3 -1
  249. package/utils/common.js +9 -3
  250. package/utils/common.js.map +1 -1
  251. package/utils/index.d.ts +6 -0
  252. package/utils/layout-helper/index.android.d.ts +1 -0
  253. package/utils/layout-helper/index.android.js +9 -0
  254. package/utils/layout-helper/index.android.js.map +1 -1
  255. package/utils/layout-helper/index.d.ts +5 -0
  256. package/utils/layout-helper/index.ios.d.ts +1 -0
  257. package/utils/layout-helper/index.ios.js +4 -0
  258. package/utils/layout-helper/index.ios.js.map +1 -1
  259. package/utils/native-helper-for-android.d.ts +14 -3
  260. package/utils/native-helper-for-android.js +57 -54
  261. package/utils/native-helper-for-android.js.map +1 -1
  262. package/utils/native-helper.android.d.ts +3 -3
  263. package/utils/native-helper.android.js +2 -2
  264. package/utils/native-helper.android.js.map +1 -1
  265. package/utils/native-helper.d.ts +22 -5
  266. package/utils/native-helper.ios.js +20 -20
  267. package/utils/native-helper.ios.js.map +1 -1
@@ -1,4 +1,6 @@
1
- import { ListViewBase, separatorColorProperty, itemTemplatesProperty } from './list-view-common';
1
+ import { ListViewBase, separatorColorProperty, itemTemplatesProperty, stickyHeaderProperty, stickyHeaderTemplateProperty, sectionedProperty, showSearchProperty } from './list-view-common';
2
+ import { View } from '../core/view';
3
+ import { PercentLength } from '../styling/length-shared';
2
4
  import { unsetValue } from '../core/properties/property-shared';
3
5
  import { Color } from '../../color';
4
6
  import { Observable } from '../../data/observable';
@@ -6,39 +8,47 @@ import { StackLayout } from '../layouts/stack-layout';
6
8
  import { ProxyViewContainer } from '../proxy-view-container';
7
9
  import { LayoutBase } from '../layouts/layout-base';
8
10
  import { profile } from '../../profiling';
11
+ import { Trace } from '../../trace';
12
+ import { Builder } from '../builder';
13
+ import { Label } from '../label';
9
14
  export * from './list-view-common';
10
15
  const ITEMLOADING = ListViewBase.itemLoadingEvent;
11
16
  const LOADMOREITEMS = ListViewBase.loadMoreItemsEvent;
12
17
  const ITEMTAP = ListViewBase.itemTapEvent;
18
+ const SEARCHCHANGE = ListViewBase.searchChangeEvent;
19
+ const STICKY_HEADER_Z_INDEX = 1000;
20
+ const SEARCH_VIEW_Z_INDEX = 2000;
21
+ // View type constants for sectioned lists
22
+ const ITEM_VIEW_TYPE = 0;
13
23
  let ItemClickListener;
14
24
  function initializeItemClickListener() {
15
25
  if (ItemClickListener) {
16
26
  return;
17
27
  }
18
- var ItemClickListenerImpl = /** @class */ (function (_super) {
19
- __extends(ItemClickListenerImpl, _super);
20
- function ItemClickListenerImpl(owner) {
21
- var _this = _super.call(this) || this;
22
- _this.owner = owner;
23
- return global.__native(_this);
24
- }
25
- ItemClickListenerImpl.prototype.onItemClick = function (parent, convertView, index, id) {
26
- var owner = this.owner;
27
- var view = owner._realizedItems.get(convertView).view;
28
- owner.notify({
29
- eventName: ITEMTAP,
30
- object: owner,
31
- index: index,
32
- view: view,
33
- });
34
- };
35
- var _a;
36
- ItemClickListenerImpl = __decorate([
37
- Interfaces([android.widget.AdapterView.OnItemClickListener]),
38
- __metadata("design:paramtypes", [typeof (_a = typeof ListView !== "undefined" && ListView) === "function" ? _a : Object])
39
- ], ItemClickListenerImpl);
40
- return ItemClickListenerImpl;
41
- }(java.lang.Object));
28
+ var ItemClickListenerImpl = (function (_super) {
29
+ __extends(ItemClickListenerImpl, _super);
30
+ function ItemClickListenerImpl(owner) {
31
+ var _this = _super.call(this) || this;
32
+ _this.owner = owner;
33
+ return global.__native(_this);
34
+ }
35
+ ItemClickListenerImpl.prototype.onItemClick = function (parent, convertView, index, id) {
36
+ var owner = this.owner;
37
+ var view = owner._realizedItems.get(convertView).view;
38
+ owner.notify({
39
+ eventName: ITEMTAP,
40
+ object: owner,
41
+ index: index,
42
+ view: view,
43
+ });
44
+ };
45
+ var _a;
46
+ ItemClickListenerImpl = __decorate([
47
+ Interfaces([android.widget.AdapterView.OnItemClickListener]),
48
+ __metadata("design:paramtypes", [typeof (_a = typeof ListView !== "undefined" && ListView) === "function" ? _a : Object])
49
+ ], ItemClickListenerImpl);
50
+ return ItemClickListenerImpl;
51
+ }(java.lang.Object));
42
52
  ItemClickListener = ItemClickListenerImpl;
43
53
  }
44
54
  export class ListView extends ListViewBase {
@@ -48,6 +58,11 @@ export class ListView extends ListViewBase {
48
58
  this._realizedItems = new Map();
49
59
  this._availableViews = new Map();
50
60
  this._realizedTemplates = new Map();
61
+ this._stickyHeaderHeight = 0;
62
+ this._hiddenHeaderPositions = new Set(); // Track which headers to hide
63
+ }
64
+ get hasSearchView() {
65
+ return !!this._searchView;
51
66
  }
52
67
  _ensureAvailableViews(templateKey) {
53
68
  if (!this._availableViews.has(templateKey)) {
@@ -122,6 +137,7 @@ export class ListView extends ListViewBase {
122
137
  this._androidViewId = android.view.View.generateViewId();
123
138
  }
124
139
  nativeView.setId(this._androidViewId);
140
+ // Don't setup search here - wait for onLoaded when context is properly available
125
141
  }
126
142
  disposeNativeView() {
127
143
  const nativeView = this.nativeViewProtected;
@@ -132,13 +148,40 @@ export class ListView extends ListViewBase {
132
148
  if (nativeView.adapter) {
133
149
  nativeView.adapter.owner = null;
134
150
  }
151
+ // Cleanup search
152
+ this._cleanupSearchView();
153
+ // Cleanup sticky header
154
+ this._cleanupStickyHeader();
135
155
  this.clearRealizedCells();
136
156
  super.disposeNativeView();
137
157
  }
158
+ _cleanupStickyHeader() {
159
+ // Remove scroll listener
160
+ if (this._scrollListener) {
161
+ this.nativeViewProtected.setOnScrollListener(null);
162
+ this._scrollListener = null;
163
+ }
164
+ // Remove sticky header from parent
165
+ if (this._stickyHeaderView && this._stickyHeaderView.parent) {
166
+ this._stickyHeaderView.parent._removeView(this._stickyHeaderView);
167
+ }
168
+ this._stickyHeaderView = null;
169
+ this._stickyHeaderHeight = 0;
170
+ // Clear hidden headers
171
+ this._hiddenHeaderPositions.clear();
172
+ }
138
173
  onLoaded() {
139
174
  super.onLoaded();
140
175
  // Without this call itemClick won't be fired... :(
141
176
  this.requestLayout();
177
+ // Setup sticky header if enabled
178
+ if (this.stickyHeader && this.sectioned && this.stickyHeaderTemplate) {
179
+ this._setupStickyHeader();
180
+ }
181
+ // Setup search if enabled and not already set up
182
+ if (this.showSearch && !this._searchView && this.nativeViewProtected && this.nativeViewProtected.getAdapter()) {
183
+ this._setupSearchView();
184
+ }
142
185
  }
143
186
  refresh() {
144
187
  const nativeView = this.nativeViewProtected;
@@ -151,7 +194,19 @@ export class ListView extends ListViewBase {
151
194
  view.bindingContext = null;
152
195
  }
153
196
  });
154
- nativeView.getAdapter().notifyDataSetChanged();
197
+ // Safely refresh the adapter - no HeaderViewListAdapter issues since we don't use headers
198
+ const adapter = nativeView.getAdapter();
199
+ if (adapter instanceof android.widget.BaseAdapter) {
200
+ try {
201
+ adapter.notifyDataSetChanged();
202
+ }
203
+ catch (error) {
204
+ if (Trace.isEnabled()) {
205
+ Trace.error('Error refreshing adapter, recreating: ' + error);
206
+ }
207
+ nativeView.setAdapter(new ListViewAdapterClass(this));
208
+ }
209
+ }
155
210
  }
156
211
  scrollToIndex(index) {
157
212
  const nativeView = this.nativeViewProtected;
@@ -212,6 +267,217 @@ export class ListView extends ListViewBase {
212
267
  const end = nativeView.getLastVisiblePosition();
213
268
  return index >= start && index <= end;
214
269
  }
270
+ // Sticky header methods
271
+ _setupStickyHeader() {
272
+ if (!this.stickyHeader || !this.sectioned || !this.stickyHeaderTemplate) {
273
+ return;
274
+ }
275
+ // Create the sticky header view
276
+ this._createStickyHeaderView();
277
+ // Add it as an overlay to the parent
278
+ this._addStickyHeaderToParent();
279
+ // Add padding to ListView so content doesn't hide behind sticky header
280
+ this._addListViewPadding();
281
+ // Setup scroll listener to update header content
282
+ this._setupScrollListener();
283
+ }
284
+ _createStickyHeaderView() {
285
+ if (this._stickyHeaderView) {
286
+ return; // Already created
287
+ }
288
+ // Create header view using the same template as section headers
289
+ if (typeof this.stickyHeaderTemplate === 'string') {
290
+ try {
291
+ this._stickyHeaderView = Builder.parse(this.stickyHeaderTemplate, this);
292
+ }
293
+ catch (error) {
294
+ // Fallback to simple label
295
+ this._stickyHeaderView = new Label();
296
+ this._stickyHeaderView.text = 'Header Error';
297
+ }
298
+ }
299
+ if (!this._stickyHeaderView) {
300
+ // Default header
301
+ this._stickyHeaderView = new Label();
302
+ this._stickyHeaderView.text = 'Section 0';
303
+ }
304
+ // Set initial binding context (section 0)
305
+ this._updateStickyHeader(0);
306
+ }
307
+ _addStickyHeaderToParent() {
308
+ if (!this._stickyHeaderView || !this.parent) {
309
+ return;
310
+ }
311
+ // Remove from current parent if it has one (likely the ListView from Builder.parse)
312
+ if (this._stickyHeaderView.parent) {
313
+ this._stickyHeaderView.parent._removeView(this._stickyHeaderView);
314
+ }
315
+ // Set proper sizing - don't stretch to fill parent
316
+ this._stickyHeaderView.width = { unit: '%', value: 100 };
317
+ this._stickyHeaderView.height = 'auto'; // Let it size to content
318
+ this._stickyHeaderView.verticalAlignment = 'top';
319
+ this._stickyHeaderView.horizontalAlignment = 'stretch';
320
+ // Add sticky header to the parent layout
321
+ // If search view exists, position sticky header after it (index 1), otherwise at top (index 0)
322
+ const parentLayout = this.parent;
323
+ const hasSearchView = this.showSearch && this._searchView && this._searchView._wrapper;
324
+ if (parentLayout instanceof StackLayout) {
325
+ const insertIndex = hasSearchView ? 1 : 0;
326
+ parentLayout.insertChild(this._stickyHeaderView, insertIndex);
327
+ }
328
+ else {
329
+ parentLayout._addView(this._stickyHeaderView);
330
+ }
331
+ // When search is enabled, position sticky header below search view with proper top margin
332
+ if (this.showSearch && this._searchView) {
333
+ // Add top margin to push sticky header below search view
334
+ this._stickyHeaderView.marginTop = 0; // Reset any previous margin
335
+ // Position sticky header with proper offset using native positioning
336
+ if (this._stickyHeaderView.nativeViewProtected) {
337
+ this._stickyHeaderView.nativeViewProtected.setZ(STICKY_HEADER_Z_INDEX);
338
+ // Use a timeout to ensure search view is measured first
339
+ setTimeout(() => {
340
+ if (this._searchView && this._searchView._wrapper) {
341
+ const searchWrapper = this._searchView._wrapper;
342
+ if (searchWrapper.nativeViewProtected) {
343
+ const searchHeight = searchWrapper.nativeViewProtected.getMeasuredHeight() || 50;
344
+ // Position sticky header below search view using translation
345
+ if (this._stickyHeaderView.nativeViewProtected) {
346
+ this._stickyHeaderView.nativeViewProtected.setTranslationY(searchHeight);
347
+ }
348
+ }
349
+ }
350
+ }, 100);
351
+ }
352
+ }
353
+ else {
354
+ // No search view - position at top
355
+ if (this._stickyHeaderView.nativeViewProtected) {
356
+ this._stickyHeaderView.nativeViewProtected.setZ(STICKY_HEADER_Z_INDEX);
357
+ this._stickyHeaderView.nativeViewProtected.setTranslationY(0);
358
+ }
359
+ }
360
+ }
361
+ _addListViewPadding() {
362
+ if (!this._stickyHeaderView) {
363
+ return;
364
+ }
365
+ // Calculate total top padding: search view height + sticky header height
366
+ let searchViewHeight = 0;
367
+ if (this.showSearch && this._searchView && this._searchView._wrapper) {
368
+ const searchWrapper = this._searchView._wrapper;
369
+ if (searchWrapper.nativeViewProtected && searchWrapper.nativeViewProtected.getMeasuredHeight() > 0) {
370
+ searchViewHeight = searchWrapper.nativeViewProtected.getMeasuredHeight();
371
+ }
372
+ else {
373
+ searchViewHeight = 50; // Default search view height
374
+ }
375
+ }
376
+ // Apply immediate padding with defaults to prevent content hiding
377
+ const defaultHeaderHeight = 50; // Reasonable default height in dp
378
+ const totalPadding = searchViewHeight + defaultHeaderHeight;
379
+ this.nativeViewProtected.setPadding(0, totalPadding, 0, 0);
380
+ this._stickyHeaderHeight = defaultHeaderHeight;
381
+ // Request layout to ensure proper measurement
382
+ this._stickyHeaderView.requestLayout();
383
+ // Then measure and adjust padding if needed using a layout listener for determinism
384
+ const stickyHeaderNativeView = this._stickyHeaderView && this._stickyHeaderView.nativeViewProtected;
385
+ if (stickyHeaderNativeView) {
386
+ const layoutListener = new android.view.View.OnLayoutChangeListener({
387
+ onLayoutChange: (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) => {
388
+ if (v.getMeasuredHeight() > 0) {
389
+ const measuredHeaderHeight = v.getMeasuredHeight();
390
+ let finalSearchHeight = searchViewHeight;
391
+ // Re-measure search view if needed
392
+ if (this.showSearch && this._searchView && this._searchView._wrapper) {
393
+ const searchWrapper = this._searchView._wrapper;
394
+ if (searchWrapper.nativeViewProtected && searchWrapper.nativeViewProtected.getMeasuredHeight() > 0) {
395
+ finalSearchHeight = searchWrapper.nativeViewProtected.getMeasuredHeight();
396
+ }
397
+ }
398
+ // Calculate final padding: search height + sticky header height + small buffer
399
+ const totalPaddingHeight = finalSearchHeight + measuredHeaderHeight + 4;
400
+ this._stickyHeaderHeight = measuredHeaderHeight;
401
+ this.nativeViewProtected.setPadding(0, totalPaddingHeight, 0, 0);
402
+ this.scrollToIndex(0);
403
+ // Remove the listener after first valid layout
404
+ v.removeOnLayoutChangeListener(layoutListener);
405
+ }
406
+ },
407
+ });
408
+ stickyHeaderNativeView.addOnLayoutChangeListener(layoutListener);
409
+ }
410
+ }
411
+ _setupScrollListener() {
412
+ if (this._scrollListener) {
413
+ return; // Already setup
414
+ }
415
+ const owner = this;
416
+ this._scrollListener = new android.widget.AbsListView.OnScrollListener({
417
+ onScrollStateChanged(view, scrollState) {
418
+ // Not needed for sticky headers
419
+ },
420
+ onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount) {
421
+ if (owner.sectioned && owner._stickyHeaderView) {
422
+ const currentSection = owner._getCurrentSection(firstVisibleItem);
423
+ owner._updateStickyHeader(currentSection);
424
+ // Hide section headers when they would appear right below sticky header
425
+ owner._updateHiddenHeaders(firstVisibleItem);
426
+ }
427
+ },
428
+ });
429
+ this.nativeViewProtected.setOnScrollListener(this._scrollListener);
430
+ }
431
+ _getCurrentSection(firstVisibleItem) {
432
+ if (!this.sectioned) {
433
+ return 0;
434
+ }
435
+ // Convert the first visible list position to section number
436
+ let currentPosition = 0;
437
+ const sectionCount = this._getSectionCount();
438
+ for (let section = 0; section < sectionCount; section++) {
439
+ // Check if firstVisibleItem is in this section (header or items)
440
+ const sectionItems = this._getItemsInSection(section) || [];
441
+ const itemsInSection = sectionItems.length || 0;
442
+ const sectionEndPosition = currentPosition + 1 + itemsInSection; // +1 for header
443
+ if (firstVisibleItem < sectionEndPosition) {
444
+ return section;
445
+ }
446
+ currentPosition = sectionEndPosition;
447
+ }
448
+ return Math.max(0, sectionCount - 1); // Fallback to last section
449
+ }
450
+ _updateStickyHeader(section) {
451
+ if (!this._stickyHeaderView) {
452
+ return;
453
+ }
454
+ // Update binding context to match the current section
455
+ const sectionData = this._getSectionData(section);
456
+ if (sectionData) {
457
+ this._stickyHeaderView.bindingContext = sectionData;
458
+ }
459
+ else {
460
+ this._stickyHeaderView.bindingContext = { title: `Section ${section}`, section: section };
461
+ }
462
+ }
463
+ _updateHiddenHeaders(firstVisibleItem) {
464
+ const previousHiddenHeaders = new Set(this._hiddenHeaderPositions);
465
+ this._hiddenHeaderPositions.clear();
466
+ // If we're at the very top (first item is position 0, which is the first section header),
467
+ // hide that section header to avoid duplication with sticky header
468
+ if (firstVisibleItem === 0) {
469
+ this._hiddenHeaderPositions.add(0); // Hide the first section header position
470
+ }
471
+ // If hidden headers changed, refresh the adapter
472
+ const hiddenHeadersChanged = previousHiddenHeaders.size !== this._hiddenHeaderPositions.size || [...previousHiddenHeaders].some((pos) => !this._hiddenHeaderPositions.has(pos));
473
+ if (hiddenHeadersChanged) {
474
+ // Refresh adapter to update visibility
475
+ const adapter = this.nativeViewProtected.getAdapter();
476
+ if (adapter instanceof android.widget.BaseAdapter) {
477
+ adapter.notifyDataSetChanged();
478
+ }
479
+ }
480
+ }
215
481
  [separatorColorProperty.getDefault]() {
216
482
  const nativeView = this.nativeViewProtected;
217
483
  return {
@@ -238,8 +504,199 @@ export class ListView extends ListViewBase {
238
504
  if (value) {
239
505
  this._itemTemplatesInternal = this._itemTemplatesInternal.concat(value);
240
506
  }
241
- this.nativeViewProtected.setAdapter(new ListViewAdapterClass(this));
242
- this.refresh();
507
+ if (this.nativeViewProtected) {
508
+ this.nativeViewProtected.setAdapter(new ListViewAdapterClass(this));
509
+ this.refresh();
510
+ }
511
+ }
512
+ // Sticky header property handlers
513
+ [stickyHeaderProperty.setNative](value) {
514
+ // Refresh adapter to handle sectioned vs non-sectioned display
515
+ if (this.nativeViewProtected && this.nativeViewProtected.getAdapter()) {
516
+ this.nativeViewProtected.setAdapter(new ListViewAdapterClass(this));
517
+ }
518
+ // Setup or cleanup sticky header
519
+ if (value && this.sectioned && this.stickyHeaderTemplate && this.isLoaded) {
520
+ this._setupStickyHeader();
521
+ }
522
+ else {
523
+ this._cleanupStickyHeader();
524
+ }
525
+ }
526
+ [stickyHeaderTemplateProperty.setNative](value) {
527
+ // Refresh adapter when template changes
528
+ if (this.nativeViewProtected && this.nativeViewProtected.getAdapter()) {
529
+ this.nativeViewProtected.setAdapter(new ListViewAdapterClass(this));
530
+ }
531
+ // Recreate sticky header with new template
532
+ this._cleanupStickyHeader();
533
+ if (value && this.stickyHeader && this.sectioned && this.isLoaded) {
534
+ this._setupStickyHeader();
535
+ }
536
+ }
537
+ [sectionedProperty.setNative](value) {
538
+ // Refresh adapter to handle sectioned vs non-sectioned data
539
+ if (this.nativeViewProtected && this.nativeViewProtected.getAdapter()) {
540
+ this.nativeViewProtected.setAdapter(new ListViewAdapterClass(this));
541
+ }
542
+ // Setup or cleanup sticky header based on sectioned state
543
+ if (value && this.stickyHeader && this.stickyHeaderTemplate && this.isLoaded) {
544
+ this._setupStickyHeader();
545
+ }
546
+ else {
547
+ this._cleanupStickyHeader();
548
+ }
549
+ }
550
+ // Search methods
551
+ _setupSearchView() {
552
+ if (this._searchView || !this.showSearch || !this.nativeViewProtected) {
553
+ return;
554
+ }
555
+ // Create SearchView using the ListView's context
556
+ this._searchView = new android.widget.SearchView(this.nativeViewProtected.getContext());
557
+ this._searchView.setQueryHint('Search...');
558
+ this._searchView.setIconifiedByDefault(false);
559
+ this._searchView.setSubmitButtonEnabled(false);
560
+ // Setup search listener
561
+ const owner = this;
562
+ this._searchListener = new android.widget.SearchView.OnQueryTextListener({
563
+ onQueryTextChange(newText) {
564
+ const args = {
565
+ eventName: SEARCHCHANGE,
566
+ object: owner,
567
+ text: newText,
568
+ android: owner._searchView,
569
+ };
570
+ owner.notify(args);
571
+ return true;
572
+ },
573
+ onQueryTextSubmit(query) {
574
+ const args = {
575
+ eventName: SEARCHCHANGE,
576
+ object: owner,
577
+ text: query,
578
+ android: owner._searchView,
579
+ };
580
+ owner.notify(args);
581
+ return true;
582
+ },
583
+ });
584
+ this._searchView.setOnQueryTextListener(this._searchListener);
585
+ // Add search view to the parent container above the ListView
586
+ this._addSearchToParent();
587
+ // Add padding to ListView if no sticky header (otherwise sticky header method handles it)
588
+ if (!this.stickyHeader || !this._stickyHeaderView) {
589
+ this._addSearchPadding();
590
+ }
591
+ }
592
+ _addSearchPadding() {
593
+ if (!this._searchView) {
594
+ return;
595
+ }
596
+ // Add basic padding for search view
597
+ const defaultSearchHeight = 50; // Default search view height
598
+ this.nativeViewProtected.setPadding(0, defaultSearchHeight, 0, 0);
599
+ // Measure and adjust if needed
600
+ setTimeout(() => {
601
+ if (this._searchView && this._searchView._wrapper) {
602
+ const searchWrapper = this._searchView._wrapper;
603
+ if (searchWrapper.nativeViewProtected && searchWrapper.nativeViewProtected.getMeasuredHeight() > 0) {
604
+ const measuredHeight = searchWrapper.nativeViewProtected.getMeasuredHeight();
605
+ this.nativeViewProtected.setPadding(0, measuredHeight + 4, 0, 0);
606
+ }
607
+ }
608
+ }, 100);
609
+ }
610
+ _addSearchToParent() {
611
+ if (!this._searchView || !this.parent) {
612
+ return;
613
+ }
614
+ // Get the parent layout
615
+ const parentLayout = this.parent;
616
+ // Create a simple NativeScript wrapper for the native SearchView
617
+ const searchView = this._searchView;
618
+ const searchViewWrapper = new (class extends View {
619
+ createNativeView() {
620
+ return searchView;
621
+ }
622
+ })();
623
+ // Set layout properties - ensure it's at the top
624
+ searchViewWrapper.height = 'auto';
625
+ searchViewWrapper.width = { unit: '%', value: 100 };
626
+ searchViewWrapper.verticalAlignment = 'top';
627
+ searchViewWrapper.horizontalAlignment = 'stretch';
628
+ // Always insert at position 0 (top) regardless of ListView position
629
+ if (parentLayout instanceof StackLayout) {
630
+ parentLayout.insertChild(searchViewWrapper, 0);
631
+ }
632
+ else {
633
+ // For other layout types, add as first child
634
+ parentLayout._addView(searchViewWrapper);
635
+ }
636
+ // Ensure search view appears above everything else
637
+ if (searchViewWrapper.nativeViewProtected) {
638
+ searchViewWrapper.nativeViewProtected.setZ(SEARCH_VIEW_Z_INDEX);
639
+ }
640
+ // Store reference for cleanup
641
+ this._searchView._wrapper = searchViewWrapper;
642
+ }
643
+ _cleanupSearchView() {
644
+ if (this._searchView) {
645
+ // Remove search view wrapper from parent
646
+ const wrapper = this._searchView._wrapper;
647
+ if (wrapper && wrapper.parent) {
648
+ wrapper.parent._removeView(wrapper);
649
+ }
650
+ // Clear listener
651
+ if (this._searchListener) {
652
+ this._searchView.setOnQueryTextListener(null);
653
+ this._searchListener = null;
654
+ }
655
+ this._searchView = null;
656
+ // Reset ListView padding if no sticky header
657
+ if (!this.stickyHeader || !this._stickyHeaderView) {
658
+ this.nativeViewProtected.setPadding(0, 0, 0, 0);
659
+ }
660
+ }
661
+ }
662
+ [showSearchProperty.setNative](value) {
663
+ if (value) {
664
+ if (this.isLoaded && this.nativeViewProtected && this.nativeViewProtected.getAdapter()) {
665
+ this._setupSearchView();
666
+ // Reposition sticky header if it exists
667
+ if (this._stickyHeaderView) {
668
+ this._repositionStickyHeader();
669
+ }
670
+ }
671
+ }
672
+ else {
673
+ this._cleanupSearchView();
674
+ // Reposition sticky header if it exists
675
+ if (this._stickyHeaderView) {
676
+ this._repositionStickyHeader();
677
+ }
678
+ }
679
+ }
680
+ _repositionStickyHeader() {
681
+ if (!this._stickyHeaderView || !this._stickyHeaderView.nativeViewProtected) {
682
+ return;
683
+ }
684
+ // Reset positioning
685
+ this._stickyHeaderView.nativeViewProtected.setTranslationY(0);
686
+ // If search is enabled, position below search view
687
+ if (this.showSearch && this._searchView && this._searchView._wrapper) {
688
+ setTimeout(() => {
689
+ const searchWrapper = this._searchView._wrapper;
690
+ if (searchWrapper.nativeViewProtected) {
691
+ const searchHeight = searchWrapper.nativeViewProtected.getMeasuredHeight() || 50;
692
+ this._stickyHeaderView.nativeViewProtected.setTranslationY(searchHeight);
693
+ }
694
+ }, 100);
695
+ }
696
+ // Update ListView padding
697
+ if (this.stickyHeader && this._stickyHeaderView) {
698
+ this._addListViewPadding();
699
+ }
243
700
  }
244
701
  }
245
702
  __decorate([
@@ -253,116 +710,295 @@ function ensureListViewAdapterClass() {
253
710
  if (ListViewAdapterClass) {
254
711
  return;
255
712
  }
256
- var ListViewAdapter = /** @class */ (function (_super) {
257
- __extends(ListViewAdapter, _super);
258
- function ListViewAdapter(owner) {
259
- var _this = _super.call(this) || this;
260
- _this.owner = owner;
261
- return global.__native(_this);
262
- }
263
- ListViewAdapter.prototype.getCount = function () {
264
- return this.owner && this.owner.items && this.owner.items.length ? this.owner.items.length : 0;
265
- };
266
- ListViewAdapter.prototype.getItem = function (i) {
267
- if (this.owner && this.owner.items && i < this.owner.items.length) {
268
- var getItem = this.owner.items.getItem;
269
- return getItem ? getItem.call(this.owner.items, i) : this.owner.items[i];
713
+ var ListViewAdapter = (function (_super) {
714
+ __extends(ListViewAdapter, _super);
715
+ function ListViewAdapter(owner) {
716
+ var _this = _super.call(this) || this;
717
+ _this.owner = owner;
718
+ return global.__native(_this);
270
719
  }
271
- return null;
272
- };
273
- ListViewAdapter.prototype.getItemId = function (i) {
274
- var item = this.getItem(i);
275
- var id = i;
276
- if (this.owner && item && this.owner.items) {
277
- id = this.owner.itemIdGenerator(item, i, this.owner.items);
278
- }
279
- return long(id);
280
- };
281
- ListViewAdapter.prototype.hasStableIds = function () {
282
- return true;
283
- };
284
- ListViewAdapter.prototype.getViewTypeCount = function () {
285
- return this.owner._itemTemplatesInternal.length;
286
- };
287
- ListViewAdapter.prototype.getItemViewType = function (index) {
288
- var template = this.owner._getItemTemplate(index);
289
- var itemViewType = this.owner._itemTemplatesInternal.indexOf(template);
290
- return itemViewType;
291
- };
292
- ListViewAdapter.prototype.getView = function (index, convertView, parent) {
293
- //this.owner._dumpRealizedTemplates();
294
- if (!this.owner) {
720
+ ListViewAdapter.prototype.getCount = function () {
721
+ if (!this.owner) {
722
+ return 0;
723
+ }
724
+ var count = 0;
725
+ if (this.owner.sectioned) {
726
+ var sectionCount = this.owner._getSectionCount();
727
+ if (!this.owner.items || sectionCount <= 0) {
728
+ return 0;
729
+ }
730
+ for (var i = 0; i < sectionCount; i++) {
731
+ var itemsInSection = this.owner._getItemsInSection(i) || [];
732
+ if (itemsInSection.length > 0) {
733
+ count += 1;
734
+ count += itemsInSection.length;
735
+ }
736
+ }
737
+ }
738
+ else {
739
+ var src = this.owner.items;
740
+ count = src && typeof src.length === "number" ? src.length : 0;
741
+ }
742
+ return Math.max(0, count);
743
+ };
744
+ ListViewAdapter.prototype.getItem = function (i) {
745
+ if (!this.owner || !this.owner.items) {
746
+ return null;
747
+ }
748
+ var totalCount = this.getCount();
749
+ if (i < 0 || i >= totalCount) {
750
+ return null;
751
+ }
752
+ if (this.owner.sectioned) {
753
+ var positionInfo = this._getPositionInfo(i);
754
+ if (positionInfo.isHeader) {
755
+ return this.owner._getSectionData(positionInfo.section);
756
+ }
757
+ else {
758
+ return this.owner._getDataItemInSection(positionInfo.section, positionInfo.itemIndex);
759
+ }
760
+ }
761
+ else {
762
+ var src = this.owner.items;
763
+ if (src && typeof src.length === "number" && i < src.length) {
764
+ var getItem = src.getItem;
765
+ return getItem ? getItem.call(src, i) : src[i];
766
+ }
767
+ }
295
768
  return null;
296
- }
297
- var totalItemCount = this.owner.items ? this.owner.items.length : 0;
298
- if (index === totalItemCount - 1) {
299
- this.owner.notify({
300
- eventName: LOADMOREITEMS,
301
- object: this.owner,
302
- });
303
- }
304
- // Recycle an existing view or create a new one if needed.
305
- var template = this.owner._getItemTemplate(index);
306
- var view;
307
- // convertView is of the wrong type
308
- if (convertView && this.owner._getKeyFromView(convertView) !== template.key) {
309
- this.owner._markViewUnused(convertView); // release this view
310
- convertView = this.owner._getAvailableView(template.key); // get a view from the right type or null
311
- }
312
- if (convertView) {
313
- view = this.owner._realizedItems.get(convertView).view;
314
- }
315
- if (!view) {
316
- view = template.createView();
317
- }
318
- var args = {
319
- eventName: ITEMLOADING,
320
- object: this.owner,
321
- index: index,
322
- view: view,
323
- android: parent,
324
- ios: undefined,
325
769
  };
326
- this.owner.notify(args);
327
- if (!args.view) {
328
- args.view = this.owner._getDefaultItemContent(index);
329
- }
330
- if (args.view) {
331
- if (this.owner._effectiveRowHeight > -1) {
332
- args.view.height = this.owner.rowHeight;
770
+ ListViewAdapter.prototype._getPositionInfo = function (position) {
771
+ if (!this.owner.sectioned) {
772
+ return { isHeader: false, section: 0, itemIndex: position };
773
+ }
774
+ var currentPosition = 0;
775
+ var sectionCount = this.owner._getSectionCount();
776
+ for (var section = 0; section < sectionCount; section++) {
777
+ var itemsInSection = this.owner._getItemsInSection(section) || [];
778
+ if (itemsInSection.length === 0) {
779
+ continue;
780
+ }
781
+ if (currentPosition === position) {
782
+ return { isHeader: true, section: section, itemIndex: -1 };
783
+ }
784
+ currentPosition++;
785
+ if (position < currentPosition + itemsInSection.length) {
786
+ var itemIndex = position - currentPosition;
787
+ return { isHeader: false, section: section, itemIndex: itemIndex };
788
+ }
789
+ currentPosition += itemsInSection.length;
790
+ }
791
+ return { isHeader: false, section: 0, itemIndex: 0 };
792
+ };
793
+ ListViewAdapter.prototype.getItemId = function (i) {
794
+ var item = this.getItem(i);
795
+ var id = i;
796
+ if (this.owner && item && this.owner.items) {
797
+ id = this.owner.itemIdGenerator(item, i, this.owner.items);
798
+ }
799
+ return long(id);
800
+ };
801
+ ListViewAdapter.prototype.hasStableIds = function () {
802
+ return true;
803
+ };
804
+ ListViewAdapter.prototype.isEnabled = function (position) {
805
+ var totalCount = this.getCount();
806
+ if (totalCount === 0 || position < 0 || position >= totalCount) {
807
+ return false;
808
+ }
809
+ if (this.owner.sectioned) {
810
+ var positionInfo = this._getPositionInfo(position);
811
+ return !positionInfo.isHeader;
812
+ }
813
+ return true;
814
+ };
815
+ ListViewAdapter.prototype.getViewTypeCount = function () {
816
+ var count = this.owner._itemTemplatesInternal.length;
817
+ if (this.owner.sectioned && this.owner.stickyHeaderTemplate) {
818
+ count += 1;
819
+ }
820
+ return count;
821
+ };
822
+ ListViewAdapter.prototype.getItemViewType = function (index) {
823
+ if (this.owner.sectioned) {
824
+ var positionInfo = this._getPositionInfo(index);
825
+ if (positionInfo.isHeader) {
826
+ return this.owner._itemTemplatesInternal.length;
827
+ }
828
+ else {
829
+ var template = this.owner._getItemTemplate(positionInfo.itemIndex);
830
+ return this.owner._itemTemplatesInternal.indexOf(template);
831
+ }
832
+ }
833
+ else {
834
+ var template = this.owner._getItemTemplate(index);
835
+ return this.owner._itemTemplatesInternal.indexOf(template);
836
+ }
837
+ };
838
+ ListViewAdapter.prototype.getView = function (index, convertView, parent) {
839
+ if (!this.owner) {
840
+ return null;
841
+ }
842
+ var totalCount = this.getCount();
843
+ if (index < 0 || index >= totalCount) {
844
+ var emptyView = new android.view.View(this.owner._context);
845
+ var layoutParams = new android.view.ViewGroup.LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT, 0);
846
+ emptyView.setLayoutParams(layoutParams);
847
+ return emptyView;
848
+ }
849
+ if (index === totalCount - 1) {
850
+ this.owner.notify({
851
+ eventName: LOADMOREITEMS,
852
+ object: this.owner,
853
+ });
854
+ }
855
+ if (this.owner.sectioned) {
856
+ var positionInfo = this._getPositionInfo(index);
857
+ if (positionInfo.isHeader) {
858
+ return this._createHeaderView(positionInfo.section, convertView, parent, index);
859
+ }
860
+ else {
861
+ return this._createItemView(positionInfo.section, positionInfo.itemIndex, convertView, parent);
862
+ }
333
863
  }
334
864
  else {
335
- args.view.height = unsetValue;
336
- }
337
- this.owner._prepareItem(args.view, index);
338
- if (!args.view.parent) {
339
- // Proxy containers should not get treated as layouts.
340
- // Wrap them in a real layout as well.
341
- if (args.view instanceof LayoutBase && !(args.view instanceof ProxyViewContainer)) {
342
- this.owner._addView(args.view);
343
- convertView = args.view.nativeViewProtected;
865
+ return this._createItemView(0, index, convertView, parent);
866
+ }
867
+ };
868
+ ListViewAdapter.prototype._createHeaderView = function (section, convertView, parent, index) {
869
+ if (this.owner._hiddenHeaderPositions.has(index)) {
870
+ var emptyView = new android.view.View(this.owner._context);
871
+ var layoutParams = new android.view.ViewGroup.LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT, 0);
872
+ emptyView.setLayoutParams(layoutParams);
873
+ return emptyView;
874
+ }
875
+ var headerView = null;
876
+ var headerViewType = this.owner._itemTemplatesInternal.length;
877
+ if (convertView) {
878
+ var existingData = this.owner._realizedItems.get(convertView);
879
+ if (existingData && existingData.templateKey === "header_".concat(headerViewType)) {
880
+ headerView = existingData.view;
881
+ }
882
+ }
883
+ if (!headerView) {
884
+ if (this.owner.stickyHeaderTemplate) {
885
+ if (typeof this.owner.stickyHeaderTemplate === "string") {
886
+ try {
887
+ headerView = Builder.parse(this.owner.stickyHeaderTemplate, this.owner);
888
+ }
889
+ catch (error) {
890
+ headerView = new Label();
891
+ headerView.text = "Header Error";
892
+ }
893
+ }
894
+ }
895
+ if (!headerView) {
896
+ headerView = new Label();
897
+ headerView.text = "Section ".concat(section);
898
+ }
899
+ if (!headerView.parent) {
900
+ if (headerView instanceof LayoutBase && !(headerView instanceof ProxyViewContainer)) {
901
+ this.owner._addView(headerView);
902
+ convertView = headerView.nativeViewProtected;
903
+ }
904
+ else {
905
+ var sp = new StackLayout();
906
+ sp.addChild(headerView);
907
+ this.owner._addView(sp);
908
+ convertView = sp.nativeViewProtected;
909
+ }
910
+ }
911
+ this.owner._realizedItems.set(convertView, {
912
+ view: headerView,
913
+ templateKey: "header_".concat(headerViewType),
914
+ });
915
+ }
916
+ var sectionData = this.owner._getSectionData(section);
917
+ if (sectionData) {
918
+ headerView.bindingContext = sectionData;
919
+ }
920
+ else {
921
+ headerView.bindingContext = { title: "Section ".concat(section), section: section };
922
+ }
923
+ return convertView;
924
+ };
925
+ ListViewAdapter.prototype._createItemView = function (section, itemIndex, convertView, parent) {
926
+ var template = this.owner._getItemTemplate(itemIndex);
927
+ var view;
928
+ if (convertView && this.owner._getKeyFromView(convertView) !== template.key) {
929
+ this.owner._markViewUnused(convertView);
930
+ convertView = this.owner._getAvailableView(template.key);
931
+ }
932
+ if (convertView) {
933
+ view = this.owner._realizedItems.get(convertView).view;
934
+ }
935
+ if (!view) {
936
+ view = template.createView();
937
+ }
938
+ var args = {
939
+ eventName: ITEMLOADING,
940
+ object: this.owner,
941
+ index: itemIndex,
942
+ view: view,
943
+ android: parent,
944
+ ios: undefined,
945
+ };
946
+ this.owner.notify(args);
947
+ if (!args.view) {
948
+ args.view = this.owner._getDefaultItemContent(itemIndex);
949
+ }
950
+ if (args.view) {
951
+ if (this.owner._effectiveRowHeight > -1) {
952
+ args.view.height = this.owner.rowHeight;
344
953
  }
345
954
  else {
346
- var sp = new StackLayout();
347
- sp.addChild(args.view);
348
- this.owner._addView(sp);
349
- convertView = sp.nativeViewProtected;
955
+ args.view.height = unsetValue;
350
956
  }
957
+ if (this.owner.sectioned) {
958
+ this.owner._prepareItemInSection(args.view, section, itemIndex);
959
+ }
960
+ else {
961
+ this.owner._prepareItem(args.view, itemIndex);
962
+ }
963
+ if (!args.view.parent) {
964
+ if (args.view instanceof LayoutBase && !(args.view instanceof ProxyViewContainer)) {
965
+ var mt = PercentLength.toDevicePixels(args.view.marginTop, 0, Number.NaN);
966
+ var mb = PercentLength.toDevicePixels(args.view.marginBottom, 0, Number.NaN);
967
+ var ml = PercentLength.toDevicePixels(args.view.marginLeft, 0, Number.NaN);
968
+ var mr = PercentLength.toDevicePixels(args.view.marginRight, 0, Number.NaN);
969
+ var hasMargins = mt > 0 || mb > 0 || ml > 0 || mr > 0;
970
+ if (hasMargins) {
971
+ var outer = new StackLayout();
972
+ outer.addChild(args.view);
973
+ this.owner._addView(outer);
974
+ convertView = outer.nativeViewProtected;
975
+ }
976
+ else {
977
+ this.owner._addView(args.view);
978
+ convertView = args.view.nativeViewProtected;
979
+ }
980
+ }
981
+ else {
982
+ var sp = new StackLayout();
983
+ sp.addChild(args.view);
984
+ this.owner._addView(sp);
985
+ convertView = sp.nativeViewProtected;
986
+ }
987
+ }
988
+ this.owner._registerViewToTemplate(template.key, convertView, args.view);
989
+ this.owner._markViewUsed(convertView);
351
990
  }
352
- this.owner._registerViewToTemplate(template.key, convertView, args.view);
353
- this.owner._markViewUsed(convertView);
354
- }
355
- return convertView;
356
- };
357
- var _a, _b, _c, _d, _e, _f;
358
- __decorate([
359
- profile,
360
- __metadata("design:type", Function),
361
- __metadata("design:paramtypes", [Number, typeof (_b = typeof android !== "undefined" && (_a = android.view) !== void 0 && _a.View) === "function" ? _b : Object, typeof (_d = typeof android !== "undefined" && (_c = android.view) !== void 0 && _c.ViewGroup) === "function" ? _d : Object]),
362
- __metadata("design:returntype", typeof (_f = typeof android !== "undefined" && (_e = android.view) !== void 0 && _e.View) === "function" ? _f : Object)
363
- ], ListViewAdapter.prototype, "getView", null);
364
- return ListViewAdapter;
365
- }(android.widget.BaseAdapter));
991
+ return convertView;
992
+ };
993
+ var _a, _b, _c, _d, _e, _f;
994
+ __decorate([
995
+ profile,
996
+ __metadata("design:type", Function),
997
+ __metadata("design:paramtypes", [Number, typeof (_b = typeof android !== "undefined" && (_a = android.view) !== void 0 && _a.View) === "function" ? _b : Object, typeof (_d = typeof android !== "undefined" && (_c = android.view) !== void 0 && _c.ViewGroup) === "function" ? _d : Object]),
998
+ __metadata("design:returntype", typeof (_f = typeof android !== "undefined" && (_e = android.view) !== void 0 && _e.View) === "function" ? _f : Object)
999
+ ], ListViewAdapter.prototype, "getView", null);
1000
+ return ListViewAdapter;
1001
+ }(android.widget.BaseAdapter));
366
1002
  ListViewAdapterClass = ListViewAdapter;
367
1003
  }
368
1004
  //# sourceMappingURL=index.android.js.map