@nativescript-community/ui-collectionview 5.3.8 → 5.3.9
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.
- package/CHANGELOG.md +4 -0
- package/angular/collectionview-comp.d.ts +82 -0
- package/angular/index.d.ts +8 -0
- package/index-common.d.ts +173 -0
- package/index-common.js +687 -0
- package/index-common.js.map +1 -0
- package/index.android.d.ts +133 -0
- package/index.android.js +1247 -0
- package/index.android.js.map +1 -0
- package/index.d.ts +50 -0
- package/index.ios.d.ts +112 -0
- package/index.ios.js +1231 -0
- package/index.ios.js.map +1 -0
- package/package.json +2 -2
- package/react/index.d.ts +119 -0
- package/react/index.js +153 -0
- package/react/index.js.map +1 -0
- package/references.d.ts +3 -0
- package/svelte/index.d.ts +20 -0
- package/svelte/index.js +138 -0
- package/svelte/index.js.map +1 -0
- package/typings/android.d.ts +90 -0
- package/typings/android.wasabeef.d.ts +843 -0
- package/typings/arv.d.ts +3706 -0
- package/typings/ios.d.ts +3 -0
- package/vue/component.d.ts +38 -0
- package/vue/component.js +105 -0
- package/vue/component.js.map +1 -0
- package/vue/index.d.ts +4 -0
- package/vue/index.js +12 -0
- package/vue/index.js.map +1 -0
- package/vue3/component.d.ts +36 -0
- package/vue3/component.js +105 -0
- package/vue3/component.js.map +1 -0
- package/vue3/index.d.ts +11 -0
- package/vue3/index.js +14 -0
- package/vue3/index.js.map +1 -0
package/index.android.js
ADDED
@@ -0,0 +1,1247 @@
|
|
1
|
+
var _a, _b;
|
2
|
+
/* eslint-disable no-redeclare */
|
3
|
+
import { ChangeType, ContentView, CoreTypes, Length, Property, ProxyViewContainer, Trace, Utils, View, ViewBase, booleanConverter, paddingBottomProperty, paddingLeftProperty, paddingRightProperty, paddingTopProperty, profile } from '@nativescript/core';
|
4
|
+
import { itemOverlapProperty, reorderLongPressEnabledProperty, reorderingEnabledProperty, reverseLayoutProperty, scrollBarIndicatorVisibleProperty } from '.';
|
5
|
+
import { CLog, CLogTypes, CollectionViewBase, ListViewViewTypes, isScrollEnabledProperty, orientationProperty } from './index-common';
|
6
|
+
export * from './index-common';
|
7
|
+
var SimpleCallback = /** @class */ (function (_super) {
|
8
|
+
__extends(SimpleCallback, _super);
|
9
|
+
function SimpleCallback(param1, param2) {
|
10
|
+
var _this = _super.call(this, param1, param2) || this;
|
11
|
+
_this.startPosition = -1;
|
12
|
+
_this.endPosition = -1;
|
13
|
+
return global.__native(_this);
|
14
|
+
}
|
15
|
+
SimpleCallback.prototype.onMove = function (recyclerview, viewHolder, target) {
|
16
|
+
var _a;
|
17
|
+
var startPosition = viewHolder.getAdapterPosition();
|
18
|
+
var endPosition = target.getAdapterPosition();
|
19
|
+
if (this.startPosition === -1) {
|
20
|
+
this.startPosition = startPosition;
|
21
|
+
}
|
22
|
+
this.endPosition = endPosition;
|
23
|
+
var owner = (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get();
|
24
|
+
if (owner) {
|
25
|
+
owner._reorderItemInSource(startPosition, endPosition);
|
26
|
+
return true;
|
27
|
+
}
|
28
|
+
return false;
|
29
|
+
};
|
30
|
+
SimpleCallback.prototype.onSelectedChanged = function (viewHolder, state) {
|
31
|
+
var _a;
|
32
|
+
if (viewHolder) {
|
33
|
+
if (this.startPosition === -1) {
|
34
|
+
this.startPosition = viewHolder.getAdapterPosition();
|
35
|
+
}
|
36
|
+
}
|
37
|
+
if (!viewHolder) {
|
38
|
+
// this is where we identify the end of the drag and call the end event
|
39
|
+
var owner = (_a = this.owner) === null || _a === void 0 ? void 0 : _a.get();
|
40
|
+
if (this.endPosition === -1) {
|
41
|
+
this.endPosition = this.startPosition;
|
42
|
+
}
|
43
|
+
if (owner) {
|
44
|
+
var item = owner.getItemAtIndex(this.startPosition);
|
45
|
+
owner._callItemReorderedEvent(this.startPosition, this.endPosition, item);
|
46
|
+
}
|
47
|
+
this.startPosition = -1;
|
48
|
+
this.endPosition = -1;
|
49
|
+
owner.isDragging = false;
|
50
|
+
}
|
51
|
+
};
|
52
|
+
SimpleCallback.prototype.onSwiped = function (viewHolder, direction) { };
|
53
|
+
SimpleCallback.prototype.isItemViewSwipeEnabled = function () {
|
54
|
+
// disabled for now
|
55
|
+
return false;
|
56
|
+
};
|
57
|
+
SimpleCallback.prototype.isLongPressDragEnabled = function () {
|
58
|
+
// we use our custom longpress gesture handler
|
59
|
+
return false;
|
60
|
+
};
|
61
|
+
return SimpleCallback;
|
62
|
+
}(androidx.recyclerview.widget.ItemTouchHelper.SimpleCallback));
|
63
|
+
var LongPressGestureListenerImpl = /** @class */ (function (_super) {
|
64
|
+
__extends(LongPressGestureListenerImpl, _super);
|
65
|
+
function LongPressGestureListenerImpl(_owner) {
|
66
|
+
var _this = _super.call(this) || this;
|
67
|
+
_this._owner = _owner;
|
68
|
+
return global.__native(_this);
|
69
|
+
}
|
70
|
+
LongPressGestureListenerImpl.prototype.onLongPress = function (motionEvent) {
|
71
|
+
var _a;
|
72
|
+
var owner = (_a = this._owner) === null || _a === void 0 ? void 0 : _a.get();
|
73
|
+
if (owner) {
|
74
|
+
owner.onReorderLongPress(motionEvent);
|
75
|
+
}
|
76
|
+
};
|
77
|
+
return LongPressGestureListenerImpl;
|
78
|
+
}(android.view.GestureDetector.SimpleOnGestureListener));
|
79
|
+
let LayoutParams;
|
80
|
+
const extraLayoutSpaceProperty = new Property({
|
81
|
+
name: 'extraLayoutSpace'
|
82
|
+
});
|
83
|
+
const itemViewCacheSizeProperty = new Property({
|
84
|
+
name: 'itemViewCacheSize'
|
85
|
+
});
|
86
|
+
const nestedScrollingEnabledProperty = new Property({
|
87
|
+
name: 'nestedScrollingEnabled',
|
88
|
+
defaultValue: true,
|
89
|
+
valueConverter: booleanConverter
|
90
|
+
});
|
91
|
+
export var SnapPosition;
|
92
|
+
(function (SnapPosition) {
|
93
|
+
SnapPosition[SnapPosition["START"] = 0] = "START";
|
94
|
+
SnapPosition[SnapPosition["END"] = 1] = "END";
|
95
|
+
})(SnapPosition || (SnapPosition = {}));
|
96
|
+
export class CollectionView extends CollectionViewBase {
|
97
|
+
constructor() {
|
98
|
+
super(...arguments);
|
99
|
+
this.templateTypeNumberString = new Map();
|
100
|
+
this.templateStringTypeNumber = new Map();
|
101
|
+
this._currentNativeItemType = 0;
|
102
|
+
this.currentSpanCount = 1;
|
103
|
+
// used to store viewHolder and thus their corresponding Views
|
104
|
+
// used to "destroy" cells when possible
|
105
|
+
this._viewHolders = new Set();
|
106
|
+
this._scrollOrLoadMoreChangeCount = 0;
|
107
|
+
this.scrolling = false;
|
108
|
+
this.needsScrollStartEvent = false;
|
109
|
+
this.animateItemUpdate = false;
|
110
|
+
this.mInPropertiesSet = false;
|
111
|
+
this.mShouldUpdateInnerSize = false;
|
112
|
+
this.mShouldUpdateSpanCount = false;
|
113
|
+
this.mShouldRefresh = false;
|
114
|
+
this.defaultPoolSize = 10;
|
115
|
+
this.desiredPoolSize = new Map();
|
116
|
+
this.isDragging = false;
|
117
|
+
this._layedOut = false;
|
118
|
+
this.bindedViewHolders = new Set();
|
119
|
+
}
|
120
|
+
onResumeNativeUpdates() {
|
121
|
+
// {N} suspends properties update on `_suspendNativeUpdates`. So we only need to do this in onResumeNativeUpdates
|
122
|
+
this.mInPropertiesSet = true;
|
123
|
+
super.onResumeNativeUpdates();
|
124
|
+
this.mInPropertiesSet = false;
|
125
|
+
if (this.mShouldUpdateInnerSize) {
|
126
|
+
this.updateInnerSize();
|
127
|
+
}
|
128
|
+
if (this.mShouldUpdateSpanCount) {
|
129
|
+
this.updateSpanCount();
|
130
|
+
}
|
131
|
+
if (this.mShouldRefresh) {
|
132
|
+
this.refresh();
|
133
|
+
}
|
134
|
+
}
|
135
|
+
createNativeView() {
|
136
|
+
// storing the class in a property for reuse in the future cause a materializing which is pretty slow!
|
137
|
+
if (!CollectionViewRecyclerView) {
|
138
|
+
CollectionViewRecyclerView = com.nativescript.collectionview.RecyclerView;
|
139
|
+
}
|
140
|
+
const recyclerView = CollectionViewRecyclerView.createRecyclerView(this._context);
|
141
|
+
// const expMgr = new RecyclerViewExpandableItemManager(null);
|
142
|
+
// adapter.setDisplayHeadersAtStartUp(true).setStickyHeaders(true); //Make headers sticky
|
143
|
+
// Endless scroll with 1 item threshold
|
144
|
+
// .setLoadingMoreAtStartUp(true)
|
145
|
+
// .setEndlessScrollListener(this, new ProgressItem())
|
146
|
+
// .setEndlessScrollThreshold(1); //Default=1
|
147
|
+
// const fastScroller = new com.l4digital.fastscroll.FastScroller(this._context);
|
148
|
+
// fastScroller.setSectionIndexer(adapter);
|
149
|
+
// fastScroller.attachRecyclerView(recyclerView);
|
150
|
+
return recyclerView;
|
151
|
+
}
|
152
|
+
initNativeView() {
|
153
|
+
super.initNativeView();
|
154
|
+
const nativeView = this.nativeViewProtected;
|
155
|
+
if (!this.recycledViewPool) {
|
156
|
+
this.recycledViewPool = new com.nativescript.collectionview.RecycledViewPool();
|
157
|
+
this.recycledViewPoolDisposeListener = new com.nativescript.collectionview.RecycledViewPool.ViewPoolListener({
|
158
|
+
onViewHolderDisposed: (holder) => {
|
159
|
+
if (Trace.isEnabled()) {
|
160
|
+
CLog(CLogTypes.log, 'onViewHolderDisposed', holder);
|
161
|
+
}
|
162
|
+
if (this._viewHolders) {
|
163
|
+
this._viewHolders.delete(holder);
|
164
|
+
}
|
165
|
+
const isNonSync = holder['defaultItemView'] === true;
|
166
|
+
const view = isNonSync ? holder.view.content : holder.view;
|
167
|
+
this.notifyForItemAtIndex(CollectionViewBase.itemDisposingEvent, view, holder.getAdapterPosition(), view.bindingContext, holder);
|
168
|
+
if (view && view.isLoaded) {
|
169
|
+
view.callUnloaded();
|
170
|
+
}
|
171
|
+
view._isAddedToNativeVisualTree = false;
|
172
|
+
//@ts-ignore
|
173
|
+
view.parent = null;
|
174
|
+
view._tearDownUI();
|
175
|
+
}
|
176
|
+
});
|
177
|
+
this.recycledViewPool.mListener = this.recycledViewPoolDisposeListener;
|
178
|
+
}
|
179
|
+
if (Trace.isEnabled() || this.hasListeners(CollectionViewBase.itemRecyclingEvent)) {
|
180
|
+
const recyclerListener = (this.recyclerListener = new androidx.recyclerview.widget.RecyclerView.RecyclerListener({
|
181
|
+
onViewRecycled: (holder) => {
|
182
|
+
if (Trace.isEnabled()) {
|
183
|
+
CLog(CLogTypes.log, 'onViewRecycled', this, nativeView, holder);
|
184
|
+
}
|
185
|
+
const isNonSync = holder['defaultItemView'] === true;
|
186
|
+
const view = isNonSync ? holder.view.content : holder.view;
|
187
|
+
this.notifyForItemAtIndex(CollectionViewBase.itemRecyclingEvent, view, holder.getAdapterPosition(), view.bindingContext, holder);
|
188
|
+
}
|
189
|
+
}));
|
190
|
+
nativeView.setRecyclerListener(recyclerListener);
|
191
|
+
}
|
192
|
+
nativeView.setRecycledViewPool(this.recycledViewPool);
|
193
|
+
let layoutManager;
|
194
|
+
if (CollectionViewBase.layoutStyles[this.layoutStyle]) {
|
195
|
+
layoutManager = CollectionViewBase.layoutStyles[this.layoutStyle].createLayout(this);
|
196
|
+
}
|
197
|
+
else {
|
198
|
+
layoutManager = new com.nativescript.collectionview.PreCachingGridLayoutManager(this._context, 1);
|
199
|
+
if (this.hasListeners(CollectionView.layoutCompletedEvent)) {
|
200
|
+
layoutManager.layoutCompletedListener = new com.nativescript.collectionview.GridLayoutManager.LayoutCompletedListener({
|
201
|
+
onLayoutCompleted: () => {
|
202
|
+
this.notify({ eventName: CollectionView.layoutCompletedEvent });
|
203
|
+
}
|
204
|
+
});
|
205
|
+
}
|
206
|
+
// layoutManager = new PreCachingGridLayoutManager(this._context, 1);
|
207
|
+
// (layoutManager as any).owner = new WeakRef(this);
|
208
|
+
}
|
209
|
+
// this.spanSize
|
210
|
+
nativeView.setLayoutManager(layoutManager);
|
211
|
+
nativeView.layoutManager = layoutManager;
|
212
|
+
nativeView.sizeChangedListener = new com.nativescript.collectionview.SizeChangedListener({
|
213
|
+
onLayout: (changed, left, top, right, bottom) => changed && this.onLayout(left, top, right, bottom),
|
214
|
+
onMeasure: (widthMeasureSpec, heightMeasureSpec) => this.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
215
|
+
});
|
216
|
+
this.spanSize = this._getSpanSize;
|
217
|
+
// const animator = new jp.wasabeef.recyclerview.animators.FadeInAnimator();
|
218
|
+
// // animator.setInterpolator(new android.view.animation.OvershootInterpolator());
|
219
|
+
// animator.setMoveDuration(200);
|
220
|
+
// Change animations are enabled by default since support-v7-recyclerview v22.
|
221
|
+
// Need to disable them when using animation indicator.
|
222
|
+
// animator.setSupportsChangeAnimations(false);
|
223
|
+
// nativeView.setItemAnimator(animator);
|
224
|
+
// enforce the first refresh for the collectionview to be ready as soon as possible
|
225
|
+
this.refresh(true);
|
226
|
+
}
|
227
|
+
disposeNativeView() {
|
228
|
+
// this.eachChildView((view) => {
|
229
|
+
// view.parent._removeView(view);
|
230
|
+
// return true;
|
231
|
+
// });
|
232
|
+
// this._realizedItems.clear();
|
233
|
+
const nativeView = this.nativeViewProtected;
|
234
|
+
nativeView.setRecyclerListener(null);
|
235
|
+
nativeView.setRecycledViewPool(null);
|
236
|
+
this.recycledViewPoolDisposeListener = null;
|
237
|
+
this.recycledViewPool = null;
|
238
|
+
if (nativeView.scrollListener) {
|
239
|
+
this.nativeView.removeOnScrollListener(nativeView.scrollListener);
|
240
|
+
nativeView.scrollListener = null;
|
241
|
+
this._nScrollListener = null;
|
242
|
+
}
|
243
|
+
nativeView.sizeChangedListener = null;
|
244
|
+
nativeView.layoutManager = null;
|
245
|
+
this._listViewAdapter = null;
|
246
|
+
this._itemTouchHelper = null;
|
247
|
+
this._simpleItemTouchCallback = null;
|
248
|
+
this.disposeViewHolderViews();
|
249
|
+
this.clearTemplateTypes();
|
250
|
+
super.disposeNativeView();
|
251
|
+
}
|
252
|
+
onLoaded() {
|
253
|
+
super.onLoaded();
|
254
|
+
this.attachScrollListener();
|
255
|
+
// this.refresh();
|
256
|
+
}
|
257
|
+
getViewForItemAtIndex(index) {
|
258
|
+
return this.enumerateViewHolders((v) => (v.getAdapterPosition() === index ? v.view : undefined));
|
259
|
+
}
|
260
|
+
//@ts-ignore
|
261
|
+
set spanSize(inter) {
|
262
|
+
if (!(typeof inter === 'function')) {
|
263
|
+
return;
|
264
|
+
}
|
265
|
+
this._getSpanSize = inter;
|
266
|
+
const layoutManager = this.layoutManager;
|
267
|
+
if (layoutManager && layoutManager['setSpanSizeLookup']) {
|
268
|
+
if (inter) {
|
269
|
+
layoutManager['setSpanSizeLookup'](new com.nativescript.collectionview.SpanSizeLookup(new com.nativescript.collectionview.SpanSizeLookup.Interface({
|
270
|
+
getSpanSize: (position) => {
|
271
|
+
const dataItem = this.getItemAtIndex(position);
|
272
|
+
return Math.min(inter(dataItem, position), this.currentSpanCount);
|
273
|
+
}
|
274
|
+
})));
|
275
|
+
}
|
276
|
+
else {
|
277
|
+
layoutManager['setSpanSizeLookup'](null);
|
278
|
+
}
|
279
|
+
}
|
280
|
+
}
|
281
|
+
get spanSize() {
|
282
|
+
return this._getSpanSize;
|
283
|
+
}
|
284
|
+
attachScrollListener() {
|
285
|
+
if (this._scrollOrLoadMoreChangeCount > 0 && this.isLoaded) {
|
286
|
+
const nativeView = this.nativeViewProtected;
|
287
|
+
if (!nativeView.scrollListener) {
|
288
|
+
this._nScrollListener = new com.nativescript.collectionview.OnScrollListener.Listener({
|
289
|
+
onScrollStateChanged: this.onScrollStateChanged.bind(this),
|
290
|
+
onScrolled: this.onScrolled.bind(this)
|
291
|
+
});
|
292
|
+
const scrollListener = new com.nativescript.collectionview.OnScrollListener(this._nScrollListener);
|
293
|
+
nativeView.addOnScrollListener(scrollListener);
|
294
|
+
nativeView.scrollListener = scrollListener;
|
295
|
+
}
|
296
|
+
}
|
297
|
+
}
|
298
|
+
detachScrollListener() {
|
299
|
+
if (this._scrollOrLoadMoreChangeCount === 0 && this.isLoaded) {
|
300
|
+
const nativeView = this.nativeViewProtected;
|
301
|
+
if (nativeView.scrollListener) {
|
302
|
+
this.nativeView.removeOnScrollListener(nativeView.scrollListener);
|
303
|
+
nativeView.scrollListener = null;
|
304
|
+
this._nScrollListener = null;
|
305
|
+
}
|
306
|
+
}
|
307
|
+
}
|
308
|
+
computeScrollEventData(view, eventName, dx, dy) {
|
309
|
+
const horizontal = this.isHorizontal();
|
310
|
+
const offset = horizontal ? view.computeHorizontalScrollOffset() : view.computeVerticalScrollOffset();
|
311
|
+
const range = horizontal ? view.computeHorizontalScrollRange() : view.computeVerticalScrollRange();
|
312
|
+
const extent = horizontal ? view.computeHorizontalScrollExtent() : view.computeVerticalScrollExtent();
|
313
|
+
return {
|
314
|
+
object: this,
|
315
|
+
eventName,
|
316
|
+
scrollOffset: offset / Utils.layout.getDisplayDensity(),
|
317
|
+
scrollOffsetPercentage: offset / (range - extent),
|
318
|
+
dx,
|
319
|
+
dy
|
320
|
+
};
|
321
|
+
}
|
322
|
+
onScrolled(view, dx, dy) {
|
323
|
+
if (!this || !this.scrolling) {
|
324
|
+
return;
|
325
|
+
}
|
326
|
+
if (this.needsScrollStartEvent) {
|
327
|
+
this.needsScrollStartEvent = false;
|
328
|
+
if (this.hasListeners(CollectionViewBase.scrollStartEvent)) {
|
329
|
+
this.notify(this.computeScrollEventData(view, CollectionViewBase.scrollStartEvent, dx, dy));
|
330
|
+
}
|
331
|
+
}
|
332
|
+
if (this.hasListeners(CollectionViewBase.scrollEvent)) {
|
333
|
+
this.notify(this.computeScrollEventData(view, CollectionViewBase.scrollEvent, dx, dy));
|
334
|
+
}
|
335
|
+
if (this.hasListeners(CollectionViewBase.loadMoreItemsEvent) && this.items) {
|
336
|
+
const layoutManager = view.getLayoutManager();
|
337
|
+
if (layoutManager['findLastCompletelyVisibleItemPosition']) {
|
338
|
+
const lastVisibleItemPos = layoutManager['findLastCompletelyVisibleItemPosition']();
|
339
|
+
const loadMoreItemIndex = this.items.length - this.loadMoreThreshold;
|
340
|
+
if (lastVisibleItemPos === loadMoreItemIndex) {
|
341
|
+
this.notify({ eventName: CollectionViewBase.loadMoreItemsEvent });
|
342
|
+
}
|
343
|
+
}
|
344
|
+
else if (layoutManager['findLastCompletelyVisibleItemPositions'] && layoutManager['getSpanCount']) {
|
345
|
+
let positions = Array.create('int', layoutManager['getSpanCount']());
|
346
|
+
positions = layoutManager['findLastCompletelyVisibleItemPositions'](positions);
|
347
|
+
let lastVisibleItemPos = 0;
|
348
|
+
for (let i = 0; i < positions.length; i++) {
|
349
|
+
if (positions[i] > lastVisibleItemPos) {
|
350
|
+
lastVisibleItemPos = positions[i];
|
351
|
+
}
|
352
|
+
}
|
353
|
+
const loadMoreItemIndex = this.items.length - this.loadMoreThreshold;
|
354
|
+
if (lastVisibleItemPos >= loadMoreItemIndex) {
|
355
|
+
this.notify({ eventName: CollectionViewBase.loadMoreItemsEvent });
|
356
|
+
}
|
357
|
+
}
|
358
|
+
}
|
359
|
+
}
|
360
|
+
onScrollStateChanged(view, newState) {
|
361
|
+
if (this.scrolling && newState === 0) {
|
362
|
+
// SCROLL_STATE_IDLE
|
363
|
+
this.scrolling = false;
|
364
|
+
if (this.hasListeners(CollectionViewBase.scrollEndEvent)) {
|
365
|
+
this.notify(this.computeScrollEventData(view, CollectionViewBase.scrollEndEvent));
|
366
|
+
}
|
367
|
+
}
|
368
|
+
else if (!this.scrolling && newState === 1) {
|
369
|
+
//SCROLL_STATE_DRAGGING
|
370
|
+
this.needsScrollStartEvent = true;
|
371
|
+
this.scrolling = true;
|
372
|
+
}
|
373
|
+
}
|
374
|
+
addEventListener(arg, callback, thisArg) {
|
375
|
+
super.addEventListener(arg, callback, thisArg);
|
376
|
+
if (arg === CollectionViewBase.scrollEvent || arg === CollectionViewBase.scrollStartEvent || arg === CollectionViewBase.scrollEndEvent || arg === CollectionViewBase.loadMoreItemsEvent) {
|
377
|
+
this._scrollOrLoadMoreChangeCount++;
|
378
|
+
this.attachScrollListener();
|
379
|
+
}
|
380
|
+
}
|
381
|
+
removeEventListener(arg, callback, thisArg) {
|
382
|
+
super.removeEventListener(arg, callback, thisArg);
|
383
|
+
if (arg === CollectionViewBase.scrollEvent || arg === CollectionViewBase.scrollStartEvent || arg === CollectionViewBase.scrollEndEvent || arg === CollectionViewBase.loadMoreItemsEvent) {
|
384
|
+
this._scrollOrLoadMoreChangeCount--;
|
385
|
+
this.detachScrollListener();
|
386
|
+
}
|
387
|
+
}
|
388
|
+
//@ts-ignore
|
389
|
+
get android() {
|
390
|
+
return this.nativeView;
|
391
|
+
}
|
392
|
+
get layoutManager() {
|
393
|
+
return this.nativeViewProtected && this.nativeViewProtected.layoutManager;
|
394
|
+
}
|
395
|
+
_getViewLayoutParams() {
|
396
|
+
if (this.isHorizontal()) {
|
397
|
+
if (!this._hlayoutParams) {
|
398
|
+
LayoutParams = LayoutParams || android.view.ViewGroup.LayoutParams;
|
399
|
+
this._hlayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
|
400
|
+
}
|
401
|
+
return this._hlayoutParams;
|
402
|
+
}
|
403
|
+
else {
|
404
|
+
if (!this._vlayoutParams) {
|
405
|
+
LayoutParams = LayoutParams || android.view.ViewGroup.LayoutParams;
|
406
|
+
this._vlayoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
|
407
|
+
}
|
408
|
+
return this._vlayoutParams;
|
409
|
+
}
|
410
|
+
}
|
411
|
+
setNativePoolSize(key, nativeIndex) {
|
412
|
+
if (this.desiredPoolSize.has(key)) {
|
413
|
+
this.nativeViewProtected.getRecycledViewPool().setMaxRecycledViews(nativeIndex, this.desiredPoolSize.get(key));
|
414
|
+
}
|
415
|
+
else {
|
416
|
+
if (this.defaultPoolSize >= 0) {
|
417
|
+
this.nativeViewProtected.getRecycledViewPool().setMaxRecycledViews(nativeIndex, this.defaultPoolSize);
|
418
|
+
}
|
419
|
+
}
|
420
|
+
}
|
421
|
+
setPoolSizes() {
|
422
|
+
if (!this.nativeViewProtected || !this.templateTypeNumberString) {
|
423
|
+
return;
|
424
|
+
}
|
425
|
+
this.desiredPoolSize.forEach((v, k) => {
|
426
|
+
if (this.templateTypeNumberString.has(k)) {
|
427
|
+
this.nativeViewProtected.getRecycledViewPool().setMaxRecycledViews(this.templateTypeNumberString.get(k), v);
|
428
|
+
}
|
429
|
+
});
|
430
|
+
}
|
431
|
+
setPoolSize(key, size) {
|
432
|
+
this.desiredPoolSize.set(key, size);
|
433
|
+
this.setPoolSizes();
|
434
|
+
}
|
435
|
+
[paddingTopProperty.getDefault]() {
|
436
|
+
return { value: this._defaultPaddingTop, unit: 'px' };
|
437
|
+
}
|
438
|
+
[paddingTopProperty.setNative](value) {
|
439
|
+
this._setPadding({ top: this.effectivePaddingTop });
|
440
|
+
}
|
441
|
+
[paddingRightProperty.getDefault]() {
|
442
|
+
return { value: this._defaultPaddingRight, unit: 'px' };
|
443
|
+
}
|
444
|
+
[paddingRightProperty.setNative](value) {
|
445
|
+
this._setPadding({ right: this.effectivePaddingRight });
|
446
|
+
}
|
447
|
+
[paddingBottomProperty.getDefault]() {
|
448
|
+
return { value: this._defaultPaddingBottom, unit: 'px' };
|
449
|
+
}
|
450
|
+
[paddingBottomProperty.setNative](value) {
|
451
|
+
this._setPadding({ bottom: this.effectivePaddingBottom });
|
452
|
+
}
|
453
|
+
[paddingLeftProperty.getDefault]() {
|
454
|
+
return { value: this._defaultPaddingLeft, unit: 'px' };
|
455
|
+
}
|
456
|
+
[paddingLeftProperty.setNative](value) {
|
457
|
+
this._setPadding({ left: this.effectivePaddingLeft });
|
458
|
+
}
|
459
|
+
[itemOverlapProperty.setNative](value) {
|
460
|
+
if (!this.decorator) {
|
461
|
+
this.decorator = new com.nativescript.collectionview.OverlapDecoration();
|
462
|
+
this.nativeViewProtected.addItemDecoration(this.decorator);
|
463
|
+
}
|
464
|
+
this.decorator.top = Length.toDevicePixels(value[0], 0);
|
465
|
+
this.decorator.right = Length.toDevicePixels(value[1], 0);
|
466
|
+
this.decorator.bottom = Length.toDevicePixels(value[2], 0);
|
467
|
+
this.decorator.left = Length.toDevicePixels(value[3], 0);
|
468
|
+
}
|
469
|
+
[orientationProperty.getDefault]() {
|
470
|
+
return 'vertical';
|
471
|
+
}
|
472
|
+
[orientationProperty.setNative](value) {
|
473
|
+
const layoutManager = this.layoutManager;
|
474
|
+
if (!layoutManager || !layoutManager['setOrientation']) {
|
475
|
+
return;
|
476
|
+
}
|
477
|
+
if (this.isHorizontal()) {
|
478
|
+
layoutManager['setOrientation'](0);
|
479
|
+
}
|
480
|
+
else {
|
481
|
+
layoutManager['setOrientation'](1);
|
482
|
+
}
|
483
|
+
this.updateScrollBarVisibility(this.scrollBarIndicatorVisible);
|
484
|
+
}
|
485
|
+
[isScrollEnabledProperty.setNative](value) {
|
486
|
+
const layoutManager = this.layoutManager;
|
487
|
+
if (layoutManager && layoutManager.setScrollEnabled) {
|
488
|
+
layoutManager.setScrollEnabled(value);
|
489
|
+
}
|
490
|
+
}
|
491
|
+
[reverseLayoutProperty.setNative](value) {
|
492
|
+
const layoutManager = this.layoutManager;
|
493
|
+
if (layoutManager && layoutManager.setReverseLayout) {
|
494
|
+
layoutManager.setReverseLayout(value);
|
495
|
+
// layoutManager['setStackFromEnd'](value);
|
496
|
+
}
|
497
|
+
}
|
498
|
+
[nestedScrollingEnabledProperty.setNative](value) {
|
499
|
+
this.nativeViewProtected.setNestedScrollingEnabled(value);
|
500
|
+
}
|
501
|
+
[extraLayoutSpaceProperty.setNative](value) {
|
502
|
+
const layoutManager = this.layoutManager;
|
503
|
+
if (layoutManager && layoutManager['setExtraLayoutSpace']) {
|
504
|
+
layoutManager['setExtraLayoutSpace'](value);
|
505
|
+
}
|
506
|
+
}
|
507
|
+
[itemViewCacheSizeProperty.setNative](value) {
|
508
|
+
this.nativeViewProtected.setItemViewCacheSize(value);
|
509
|
+
}
|
510
|
+
[scrollBarIndicatorVisibleProperty.getDefault]() {
|
511
|
+
return true;
|
512
|
+
}
|
513
|
+
[scrollBarIndicatorVisibleProperty.setNative](value) {
|
514
|
+
this.updateScrollBarVisibility(value);
|
515
|
+
}
|
516
|
+
updateScrollBarVisibility(value) {
|
517
|
+
if (!this.nativeViewProtected) {
|
518
|
+
return;
|
519
|
+
}
|
520
|
+
if (this.orientation === 'horizontal') {
|
521
|
+
this.nativeViewProtected.setHorizontalScrollBarEnabled(value);
|
522
|
+
}
|
523
|
+
else {
|
524
|
+
this.nativeViewProtected.setVerticalScrollBarEnabled(value);
|
525
|
+
}
|
526
|
+
}
|
527
|
+
enumerateViewHolders(cb) {
|
528
|
+
let result, v;
|
529
|
+
for (let it = this._viewHolders.values(), cellItemView = null; (cellItemView = it.next().value);) {
|
530
|
+
if (cellItemView['position'] === undefined) {
|
531
|
+
continue;
|
532
|
+
}
|
533
|
+
result = cb(cellItemView);
|
534
|
+
if (result) {
|
535
|
+
return result;
|
536
|
+
}
|
537
|
+
}
|
538
|
+
return result;
|
539
|
+
}
|
540
|
+
async enumerateViewHoldersAsync(cb) {
|
541
|
+
let result, v;
|
542
|
+
for (let it = this._viewHolders.values(), cellItemView = null; (cellItemView = it.next().value);) {
|
543
|
+
if (cellItemView['position'] === undefined) {
|
544
|
+
continue;
|
545
|
+
}
|
546
|
+
result = await cb(cellItemView);
|
547
|
+
if (result) {
|
548
|
+
return result;
|
549
|
+
}
|
550
|
+
}
|
551
|
+
return result;
|
552
|
+
}
|
553
|
+
startDragging(index) {
|
554
|
+
if (this.reorderEnabled && this._itemTouchHelper) {
|
555
|
+
// let viewHolder: CollectionViewCellHolder;
|
556
|
+
const viewHolder = this.enumerateViewHolders((v) => (v.getAdapterPosition() === index ? v : undefined));
|
557
|
+
if (viewHolder) {
|
558
|
+
this.startViewHolderDragging(index, viewHolder);
|
559
|
+
}
|
560
|
+
}
|
561
|
+
}
|
562
|
+
startViewHolderDragging(index, viewHolder) {
|
563
|
+
// isDragging is to prevent longPress from triggering and starting a new drag
|
564
|
+
// when triggered manually
|
565
|
+
if (!this.isDragging && this.shouldMoveItemAtIndex(index)) {
|
566
|
+
this.isDragging = true;
|
567
|
+
this._itemTouchHelper.startDrag(viewHolder);
|
568
|
+
}
|
569
|
+
}
|
570
|
+
onReorderLongPress(motionEvent) {
|
571
|
+
const collectionView = this.nativeViewProtected;
|
572
|
+
if (!collectionView) {
|
573
|
+
return;
|
574
|
+
}
|
575
|
+
const view = collectionView.findChildViewUnder(motionEvent.getX(), motionEvent.getY());
|
576
|
+
const viewHolder = view != null ? collectionView.getChildViewHolder(view) : null;
|
577
|
+
if (viewHolder) {
|
578
|
+
this.startViewHolderDragging(viewHolder.getAdapterPosition(), viewHolder);
|
579
|
+
}
|
580
|
+
}
|
581
|
+
_reorderItemInSource(oldPosition, newPosition) {
|
582
|
+
const adapter = this._listViewAdapter;
|
583
|
+
// 3. Tell adapter to render the model update.
|
584
|
+
adapter.notifyItemMoved(oldPosition, newPosition);
|
585
|
+
// on android _reorderItemInSource is call on every "move" and needs to update the adapter/items
|
586
|
+
// we will call events only at then end
|
587
|
+
super._reorderItemInSource(oldPosition, newPosition, false);
|
588
|
+
}
|
589
|
+
[_a = reorderLongPressEnabledProperty.setNative](value) {
|
590
|
+
if (value) {
|
591
|
+
if (!this._longPressGesture) {
|
592
|
+
this._longPressGesture = new androidx.core.view.GestureDetectorCompat(this._context, new LongPressGestureListenerImpl(new WeakRef(this)));
|
593
|
+
this._itemTouchListerner = new androidx.recyclerview.widget.RecyclerView.OnItemTouchListener({
|
594
|
+
onInterceptTouchEvent: (view, event) => {
|
595
|
+
if (this.reorderEnabled && this._longPressGesture) {
|
596
|
+
this._longPressGesture.onTouchEvent(event);
|
597
|
+
}
|
598
|
+
return false;
|
599
|
+
},
|
600
|
+
onTouchEvent: (param0, param1) => { },
|
601
|
+
onRequestDisallowInterceptTouchEvent: (disallowIntercept) => { }
|
602
|
+
});
|
603
|
+
}
|
604
|
+
this.nativeViewProtected.addOnItemTouchListener(this._itemTouchListerner);
|
605
|
+
}
|
606
|
+
else {
|
607
|
+
if (this._itemTouchListerner) {
|
608
|
+
this.nativeViewProtected.removeOnItemTouchListener(this._itemTouchListerner);
|
609
|
+
}
|
610
|
+
}
|
611
|
+
}
|
612
|
+
[_b = reorderingEnabledProperty.setNative](value) {
|
613
|
+
if (value) {
|
614
|
+
if (!this._simpleItemTouchCallback) {
|
615
|
+
const ItemTouchHelper = androidx.recyclerview.widget.ItemTouchHelper;
|
616
|
+
this._simpleItemTouchCallback = new SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.START | ItemTouchHelper.END, 0);
|
617
|
+
this._simpleItemTouchCallback.owner = new WeakRef(this);
|
618
|
+
this._itemTouchHelper = new androidx.recyclerview.widget.ItemTouchHelper(this._simpleItemTouchCallback);
|
619
|
+
this._itemTouchHelper.attachToRecyclerView(this.nativeViewProtected);
|
620
|
+
}
|
621
|
+
}
|
622
|
+
}
|
623
|
+
onItemViewLoaderChanged() {
|
624
|
+
if (this.itemViewLoader) {
|
625
|
+
this.refresh();
|
626
|
+
}
|
627
|
+
}
|
628
|
+
onItemTemplateSelectorChanged(oldValue, newValue) {
|
629
|
+
super.onItemTemplateSelectorChanged(oldValue, newValue);
|
630
|
+
this.clearTemplateTypes();
|
631
|
+
this.refresh();
|
632
|
+
}
|
633
|
+
onItemTemplateChanged(oldValue, newValue) {
|
634
|
+
super.onItemTemplateChanged(oldValue, newValue); // TODO: update current template with the new one
|
635
|
+
this.refresh();
|
636
|
+
}
|
637
|
+
onItemTemplatesChanged(oldValue, newValue) {
|
638
|
+
super.onItemTemplatesChanged(oldValue, newValue); // TODO: update current template with the new one
|
639
|
+
this.refresh();
|
640
|
+
}
|
641
|
+
updateSpanCount(requestLayout = true) {
|
642
|
+
if (this.mInPropertiesSet) {
|
643
|
+
this.mShouldUpdateSpanCount = true;
|
644
|
+
return false;
|
645
|
+
}
|
646
|
+
this.mShouldUpdateSpanCount = false;
|
647
|
+
const layoutManager = this.layoutManager;
|
648
|
+
if (layoutManager && layoutManager['setSpanCount']) {
|
649
|
+
const newValue = (this.currentSpanCount = this.computeSpanCount());
|
650
|
+
if (newValue !== layoutManager['getSpanCount']()) {
|
651
|
+
layoutManager['setSpanCount'](newValue);
|
652
|
+
if (requestLayout) {
|
653
|
+
layoutManager.requestLayout();
|
654
|
+
}
|
655
|
+
return true;
|
656
|
+
}
|
657
|
+
}
|
658
|
+
return false;
|
659
|
+
}
|
660
|
+
updateInnerSize() {
|
661
|
+
if (this.mInPropertiesSet) {
|
662
|
+
this.mShouldUpdateInnerSize = true;
|
663
|
+
return false;
|
664
|
+
}
|
665
|
+
this.mShouldUpdateInnerSize = false;
|
666
|
+
const result = super.updateInnerSize();
|
667
|
+
if (result) {
|
668
|
+
this.updateSpanCount();
|
669
|
+
}
|
670
|
+
// there is no need to call refresh if it was triggered before with same size.
|
671
|
+
// this refresh is just to handle size change
|
672
|
+
const layoutKey = this._innerWidth + '_' + this._innerHeight;
|
673
|
+
if (this._isDataDirty || (this._lastLayoutKey && this._lastLayoutKey !== layoutKey)) {
|
674
|
+
// setTimeout(() => this.refresh(false), 0);
|
675
|
+
}
|
676
|
+
this._lastLayoutKey = layoutKey;
|
677
|
+
return result;
|
678
|
+
}
|
679
|
+
_onColWidthPropertyChanged(oldValue, newValue) {
|
680
|
+
this.updateSpanCount();
|
681
|
+
super._onColWidthPropertyChanged(oldValue, newValue);
|
682
|
+
}
|
683
|
+
_onRowHeightPropertyChanged(oldValue, newValue) {
|
684
|
+
this.updateSpanCount();
|
685
|
+
super._onRowHeightPropertyChanged(oldValue, newValue);
|
686
|
+
}
|
687
|
+
onLayout(left, top, right, bottom) {
|
688
|
+
this._layedOut = true;
|
689
|
+
// super.onLayout(left, top, right, bottom);
|
690
|
+
const p = CollectionViewBase.plugins[this.layoutStyle];
|
691
|
+
if (p && p.onLayout) {
|
692
|
+
p.onLayout(this, left, top, right, bottom);
|
693
|
+
}
|
694
|
+
this.plugins.forEach((k) => {
|
695
|
+
const p = CollectionViewBase.plugins[k];
|
696
|
+
p.onLayout && p.onLayout(this, left, top, right, bottom);
|
697
|
+
});
|
698
|
+
}
|
699
|
+
onMeasure(widthMeasureSpec, heightMeasureSpec) {
|
700
|
+
const lastLayoutKey = this._lastLayoutKey;
|
701
|
+
this.updateInnerSize();
|
702
|
+
if (lastLayoutKey !== this._lastLayoutKey) {
|
703
|
+
//we need to refresh visible cells so that they measure to the new size
|
704
|
+
// for some reason it gets animated even with setSupportsChangeAnimations(false)
|
705
|
+
// so we clear until it is done
|
706
|
+
const nativeView = this.nativeViewProtected;
|
707
|
+
const animator = nativeView.getItemAnimator();
|
708
|
+
nativeView.setItemAnimator(null);
|
709
|
+
this.refreshVisibleItems();
|
710
|
+
setTimeout(() => {
|
711
|
+
nativeView.setItemAnimator(animator);
|
712
|
+
}, 0);
|
713
|
+
}
|
714
|
+
const p = CollectionViewBase.plugins[this.layoutStyle];
|
715
|
+
if (p && p.onMeasure) {
|
716
|
+
p.onMeasure(this, widthMeasureSpec, heightMeasureSpec);
|
717
|
+
}
|
718
|
+
this.plugins.forEach((k) => {
|
719
|
+
const p = CollectionViewBase.plugins[k];
|
720
|
+
p.onMeasure && p.onMeasure(this, widthMeasureSpec, heightMeasureSpec);
|
721
|
+
});
|
722
|
+
}
|
723
|
+
onSourceCollectionChanged(event) {
|
724
|
+
if (!this._listViewAdapter || this._dataUpdatesSuspended) {
|
725
|
+
return;
|
726
|
+
}
|
727
|
+
if (Trace.isEnabled()) {
|
728
|
+
CLog(CLogTypes.log, 'onItemsChanged', event.action, event.index, event.addedCount, event.removed, event.removed && event.removed.length);
|
729
|
+
}
|
730
|
+
switch (event.action) {
|
731
|
+
case ChangeType.Delete: {
|
732
|
+
this._listViewAdapter.notifyItemRangeRemoved(event.index, event.removed.length);
|
733
|
+
return;
|
734
|
+
}
|
735
|
+
case ChangeType.Add: {
|
736
|
+
if (event.addedCount > 0) {
|
737
|
+
this._listViewAdapter.notifyItemRangeInserted(event.index, event.addedCount);
|
738
|
+
}
|
739
|
+
// Reload the items to avoid duplicate Load on Demand indicators:
|
740
|
+
return;
|
741
|
+
}
|
742
|
+
case ChangeType.Update: {
|
743
|
+
if (event.addedCount > 0) {
|
744
|
+
this._listViewAdapter.notifyItemRangeChanged(event.index, event.addedCount);
|
745
|
+
}
|
746
|
+
return;
|
747
|
+
}
|
748
|
+
case ChangeType.Splice: {
|
749
|
+
const added = event.addedCount;
|
750
|
+
const removed = (event.removed && event.removed.length) || 0;
|
751
|
+
if (added > 0 && added === removed) {
|
752
|
+
// notifyItemRangeChanged wont create a fade effect
|
753
|
+
if (!this.animateItemUpdate) {
|
754
|
+
this._listViewAdapter.notifyItemRangeChanged(event.index, added);
|
755
|
+
}
|
756
|
+
else {
|
757
|
+
this._listViewAdapter.notifyItemRangeRemoved(event.index, added);
|
758
|
+
this._listViewAdapter.notifyItemRangeInserted(event.index, added);
|
759
|
+
}
|
760
|
+
}
|
761
|
+
else {
|
762
|
+
if (!this.animateItemUpdate) {
|
763
|
+
if (added > removed) {
|
764
|
+
if (removed > 0) {
|
765
|
+
this._listViewAdapter.notifyItemRangeChanged(event.index, removed);
|
766
|
+
}
|
767
|
+
this._listViewAdapter.notifyItemRangeInserted(event.index + removed, added - removed);
|
768
|
+
}
|
769
|
+
else {
|
770
|
+
if (added > 0) {
|
771
|
+
this._listViewAdapter.notifyItemRangeChanged(event.index, added);
|
772
|
+
}
|
773
|
+
this._listViewAdapter.notifyItemRangeRemoved(event.index + added, removed - added);
|
774
|
+
}
|
775
|
+
}
|
776
|
+
else {
|
777
|
+
if (event.removed && event.removed.length > 0) {
|
778
|
+
this._listViewAdapter.notifyItemRangeRemoved(event.index, event.removed.length);
|
779
|
+
}
|
780
|
+
if (event.addedCount > 0) {
|
781
|
+
this._listViewAdapter.notifyItemRangeInserted(event.index, event.addedCount);
|
782
|
+
}
|
783
|
+
}
|
784
|
+
}
|
785
|
+
return;
|
786
|
+
}
|
787
|
+
}
|
788
|
+
this._listViewAdapter.notifyDataSetChanged();
|
789
|
+
}
|
790
|
+
eachChild(callback) {
|
791
|
+
// used for css updates (like theme change)
|
792
|
+
this.enumerateViewHolders((v) => {
|
793
|
+
const view = v.view;
|
794
|
+
if (view) {
|
795
|
+
if (view.parent instanceof CollectionView) {
|
796
|
+
callback(view);
|
797
|
+
}
|
798
|
+
else {
|
799
|
+
// in some cases (like item is unloaded from another place (like angular) view.parent becomes undefined)
|
800
|
+
if (view.parent) {
|
801
|
+
callback(view.parent);
|
802
|
+
}
|
803
|
+
}
|
804
|
+
}
|
805
|
+
});
|
806
|
+
}
|
807
|
+
async eachChildAsync(callback) {
|
808
|
+
return this.enumerateViewHoldersAsync(async (v) => {
|
809
|
+
const view = v.view;
|
810
|
+
if (view) {
|
811
|
+
if (view.parent instanceof CollectionView) {
|
812
|
+
await callback(view);
|
813
|
+
}
|
814
|
+
else {
|
815
|
+
// in some cases (like item is unloaded from another place (like angular) view.parent becomes undefined)
|
816
|
+
if (view.parent) {
|
817
|
+
await callback(view.parent);
|
818
|
+
}
|
819
|
+
}
|
820
|
+
}
|
821
|
+
});
|
822
|
+
}
|
823
|
+
refreshVisibleItems() {
|
824
|
+
const view = this.nativeViewProtected;
|
825
|
+
if (!view) {
|
826
|
+
return;
|
827
|
+
}
|
828
|
+
const ids = Array.from(this.bindedViewHolders).sort((a, b) => a - b);
|
829
|
+
this._listViewAdapter.notifyItemRangeChanged(ids[0], ids[ids.length - 1] - ids[0] + 1);
|
830
|
+
}
|
831
|
+
isItemAtIndexVisible(index) {
|
832
|
+
const view = this.nativeViewProtected;
|
833
|
+
if (!view) {
|
834
|
+
return false;
|
835
|
+
}
|
836
|
+
const layoutManager = this.layoutManager;
|
837
|
+
if (layoutManager['findFirstVisibleItemPosition']) {
|
838
|
+
const first = layoutManager.findFirstVisibleItemPosition();
|
839
|
+
const last = layoutManager.findLastVisibleItemPosition();
|
840
|
+
return index >= first && index <= last;
|
841
|
+
}
|
842
|
+
return false;
|
843
|
+
}
|
844
|
+
refresh(forceRefresh = false, updateSpanCountRequestsLayout = false) {
|
845
|
+
if (this.mInPropertiesSet) {
|
846
|
+
this.mShouldRefresh = true;
|
847
|
+
return;
|
848
|
+
}
|
849
|
+
this.mShouldRefresh = false;
|
850
|
+
const view = this.nativeViewProtected;
|
851
|
+
if (!view) {
|
852
|
+
return;
|
853
|
+
}
|
854
|
+
// seems like we refresh sooner
|
855
|
+
// not sure why it was needed before and not now.
|
856
|
+
if (!forceRefresh && (!this.isLoaded || !this.nativeView)) {
|
857
|
+
this._isDataDirty = true;
|
858
|
+
return;
|
859
|
+
}
|
860
|
+
this._isDataDirty = false;
|
861
|
+
this._lastLayoutKey = this._innerWidth + '_' + this._innerHeight;
|
862
|
+
let adapter = this._listViewAdapter;
|
863
|
+
if (!adapter) {
|
864
|
+
adapter = this._listViewAdapter = this.createComposedAdapter(view);
|
865
|
+
adapter.setHasStableIds(!!this._itemIdGenerator);
|
866
|
+
view.setAdapter(adapter);
|
867
|
+
}
|
868
|
+
else if (!view.getAdapter()) {
|
869
|
+
view.setAdapter(adapter);
|
870
|
+
}
|
871
|
+
this.updateSpanCount(updateSpanCountRequestsLayout);
|
872
|
+
adapter.notifyDataSetChanged();
|
873
|
+
this.notify({ eventName: CollectionViewBase.dataPopulatedEvent });
|
874
|
+
}
|
875
|
+
//@ts-ignore
|
876
|
+
get scrollOffset() {
|
877
|
+
const view = this.nativeViewProtected;
|
878
|
+
if (!view) {
|
879
|
+
return 0;
|
880
|
+
}
|
881
|
+
return (this.isHorizontal() ? view.computeHorizontalScrollOffset() : view.computeVerticalScrollOffset()) / Utils.layout.getDisplayDensity();
|
882
|
+
}
|
883
|
+
get verticalOffsetX() {
|
884
|
+
const view = this.nativeViewProtected;
|
885
|
+
if (!view) {
|
886
|
+
return 0;
|
887
|
+
}
|
888
|
+
return view.computeHorizontalScrollOffset() / Utils.layout.getDisplayDensity();
|
889
|
+
}
|
890
|
+
get verticalOffsetY() {
|
891
|
+
const view = this.nativeViewProtected;
|
892
|
+
if (!view) {
|
893
|
+
return 0;
|
894
|
+
}
|
895
|
+
return view.computeVerticalScrollOffset() / Utils.layout.getDisplayDensity();
|
896
|
+
}
|
897
|
+
scrollToIndex(index, animated = true, snap = SnapPosition.START) {
|
898
|
+
const view = this.nativeViewProtected;
|
899
|
+
if (!view) {
|
900
|
+
return;
|
901
|
+
}
|
902
|
+
if (animated) {
|
903
|
+
view.smoothScrollToPosition(index, snap);
|
904
|
+
}
|
905
|
+
else {
|
906
|
+
view.scrollToPosition(index);
|
907
|
+
}
|
908
|
+
}
|
909
|
+
scrollToOffset(offSetValue) {
|
910
|
+
const view = this.nativeViewProtected;
|
911
|
+
if (view && this.isScrollEnabled) {
|
912
|
+
if (this.orientation === 'horizontal') {
|
913
|
+
view.scrollBy(offSetValue, 0);
|
914
|
+
}
|
915
|
+
else {
|
916
|
+
view.scrollBy(0, offSetValue);
|
917
|
+
}
|
918
|
+
}
|
919
|
+
}
|
920
|
+
_setPadding(newPadding) {
|
921
|
+
const nativeView = this.nativeViewProtected;
|
922
|
+
const padding = {
|
923
|
+
top: nativeView.getPaddingTop(),
|
924
|
+
right: nativeView.getPaddingRight(),
|
925
|
+
bottom: nativeView.getPaddingBottom(),
|
926
|
+
left: nativeView.getPaddingLeft()
|
927
|
+
};
|
928
|
+
// tslint:disable-next-line:prefer-object-spread
|
929
|
+
const newValue = Object.assign(padding, newPadding);
|
930
|
+
nativeView.setClipToPadding(false);
|
931
|
+
nativeView.setPadding(newValue.left, newValue.top, newValue.right, newValue.bottom);
|
932
|
+
this.updateInnerSize();
|
933
|
+
}
|
934
|
+
createComposedAdapter(recyclerView) {
|
935
|
+
const adapter = new com.nativescript.collectionview.Adapter();
|
936
|
+
adapter.adapterInterface = new com.nativescript.collectionview.AdapterInterface({
|
937
|
+
getItemId: this.getItemId.bind(this),
|
938
|
+
getItemViewType: this.getItemViewType.bind(this),
|
939
|
+
getItemCount: this.getItemCount.bind(this),
|
940
|
+
onCreateViewHolder: this.onCreateViewHolder.bind(this),
|
941
|
+
onBindViewHolder: this.onBindViewHolder.bind(this),
|
942
|
+
onViewRecycled: this.onViewRecycled.bind(this)
|
943
|
+
});
|
944
|
+
// const composedAdapter = new com.h6ah4i.android.widget.advrecyclerview.composedadapter.ComposedAdapter();
|
945
|
+
// composedAdapter.addAdapter(new CollectionViewAdapter(new WeakRef(this)));
|
946
|
+
return adapter;
|
947
|
+
}
|
948
|
+
getItemCount() {
|
949
|
+
return this.items ? this.items.length : 0;
|
950
|
+
}
|
951
|
+
getItem(i) {
|
952
|
+
if (this.items && i < this.items.length) {
|
953
|
+
return this.getItemAtIndex(i);
|
954
|
+
}
|
955
|
+
return null;
|
956
|
+
}
|
957
|
+
getItemId(i) {
|
958
|
+
let id = -1;
|
959
|
+
if (this._itemIdGenerator && this.items) {
|
960
|
+
const item = this.getItemAtIndex(i);
|
961
|
+
id = this._itemIdGenerator(item, i, this.items);
|
962
|
+
}
|
963
|
+
return long(id);
|
964
|
+
}
|
965
|
+
onItemIdGeneratorChanged(oldValue, newValue) {
|
966
|
+
super.onItemIdGeneratorChanged(oldValue, newValue);
|
967
|
+
if (this._listViewAdapter) {
|
968
|
+
this._listViewAdapter.setHasStableIds(!!newValue);
|
969
|
+
}
|
970
|
+
}
|
971
|
+
clearTemplateTypes() {
|
972
|
+
this._currentNativeItemType = 0;
|
973
|
+
this.templateTypeNumberString.clear();
|
974
|
+
this.templateStringTypeNumber.clear();
|
975
|
+
}
|
976
|
+
getItemViewType(position) {
|
977
|
+
let selectorType = 'default';
|
978
|
+
if (this._itemTemplateSelector) {
|
979
|
+
const selector = this._itemTemplateSelector;
|
980
|
+
const dataItem = this.getItemAtIndex(position);
|
981
|
+
if (dataItem) {
|
982
|
+
selectorType = selector.call(this, dataItem, position, this.items);
|
983
|
+
}
|
984
|
+
}
|
985
|
+
return this.templateKeyToNativeItem(selectorType);
|
986
|
+
// if (!this.templateTypeNumberString.has(selectorType)) {
|
987
|
+
// resultType = this._currentNativeItemType;
|
988
|
+
// this.templateTypeNumberString.set(selectorType, resultType);
|
989
|
+
// this.templateStringTypeNumber.set(resultType, selectorType);
|
990
|
+
// this._currentNativeItemType++;
|
991
|
+
// } else {
|
992
|
+
// resultType = this.templateTypeNumberString.get(selectorType);
|
993
|
+
// }
|
994
|
+
// return resultType;
|
995
|
+
}
|
996
|
+
templateKeyToNativeItem(key) {
|
997
|
+
if (!this.templateTypeNumberString) {
|
998
|
+
this.templateTypeNumberString = new Map();
|
999
|
+
this._currentNativeItemType = 0;
|
1000
|
+
this._itemTemplatesInternal.forEach((v, i) => {
|
1001
|
+
this.templateTypeNumberString.set(v.key, this._currentNativeItemType);
|
1002
|
+
this.templateStringTypeNumber.set(this._currentNativeItemType, v.key);
|
1003
|
+
this.setNativePoolSize(v.key, this._currentNativeItemType);
|
1004
|
+
this._currentNativeItemType++;
|
1005
|
+
});
|
1006
|
+
this._currentNativeItemType = Math.max(this._itemTemplatesInternal.size, 100);
|
1007
|
+
// templates will be numbered 0,1,2,3... for named templates
|
1008
|
+
// default/unnamed templates will be numbered 100, 101, 102, 103...
|
1009
|
+
}
|
1010
|
+
if (!this.templateTypeNumberString.has(key)) {
|
1011
|
+
this.templateTypeNumberString.set(key, this._currentNativeItemType);
|
1012
|
+
this.templateStringTypeNumber.set(this._currentNativeItemType, key);
|
1013
|
+
this.setNativePoolSize(key, this._currentNativeItemType);
|
1014
|
+
this._currentNativeItemType++;
|
1015
|
+
}
|
1016
|
+
return this.templateTypeNumberString.get(key);
|
1017
|
+
}
|
1018
|
+
// public nativeItemToTemplateKey(item: number): string {
|
1019
|
+
// let result: string;
|
1020
|
+
// this.templateTypeNumberString?.forEach((value, key, map) => {
|
1021
|
+
// if (value === item) {
|
1022
|
+
// result = key;
|
1023
|
+
// }
|
1024
|
+
// }, this);
|
1025
|
+
// return result;
|
1026
|
+
// }
|
1027
|
+
disposeViewHolderViews() {
|
1028
|
+
this.enumerateViewHolders((v) => {
|
1029
|
+
const view = v.view;
|
1030
|
+
if (view) {
|
1031
|
+
if (view.isLoaded) {
|
1032
|
+
view.callUnloaded();
|
1033
|
+
}
|
1034
|
+
view._isAddedToNativeVisualTree = false;
|
1035
|
+
view._tearDownUI();
|
1036
|
+
}
|
1037
|
+
v.view = null;
|
1038
|
+
v.clickListener = null;
|
1039
|
+
});
|
1040
|
+
this._viewHolders = new Set();
|
1041
|
+
}
|
1042
|
+
getKeyByValue(viewType) {
|
1043
|
+
return this.templateStringTypeNumber.get(viewType);
|
1044
|
+
}
|
1045
|
+
onCreateViewHolder(parent, viewType) {
|
1046
|
+
const start = Date.now();
|
1047
|
+
let view = this.getViewForViewType(ListViewViewTypes.ItemView, this.getKeyByValue(viewType));
|
1048
|
+
const isNonSync = view === undefined;
|
1049
|
+
// dont create unecessary StackLayout if template.createView returns. Will happend when not using Vue or angular
|
1050
|
+
if (isNonSync || view instanceof ProxyViewContainer) {
|
1051
|
+
const parentView = new ContentView();
|
1052
|
+
parentView.id = 'collectionViewHolder';
|
1053
|
+
view = parentView;
|
1054
|
+
}
|
1055
|
+
view._setupAsRootView(this._context);
|
1056
|
+
view._isAddedToNativeVisualTree = true;
|
1057
|
+
//@ts-ignore
|
1058
|
+
view.parent = this;
|
1059
|
+
view.callLoaded();
|
1060
|
+
if (!CollectionViewCellHolder) {
|
1061
|
+
CollectionViewCellHolder = com.nativescript.collectionview.CollectionViewCellHolder;
|
1062
|
+
}
|
1063
|
+
const holder = new CollectionViewCellHolder(view.nativeView);
|
1064
|
+
const collectionView = this;
|
1065
|
+
const clickListener = new android.view.View.OnClickListener({
|
1066
|
+
onClick: () => {
|
1067
|
+
const position = holder.getAdapterPosition();
|
1068
|
+
collectionView.notify({
|
1069
|
+
eventName: CollectionViewBase.itemTapEvent,
|
1070
|
+
object: collectionView,
|
1071
|
+
index: position,
|
1072
|
+
item: collectionView.getItem(position),
|
1073
|
+
view: holder.view
|
1074
|
+
});
|
1075
|
+
}
|
1076
|
+
});
|
1077
|
+
view.nativeView.setOnClickListener(clickListener);
|
1078
|
+
holder.clickListener = clickListener;
|
1079
|
+
holder.view = view;
|
1080
|
+
const layoutParams = this._getViewLayoutParams();
|
1081
|
+
view.nativeView.setLayoutParams(layoutParams);
|
1082
|
+
if (isNonSync) {
|
1083
|
+
holder['defaultItemView'] = true;
|
1084
|
+
}
|
1085
|
+
this._viewHolders.add(holder);
|
1086
|
+
if (Trace.isEnabled()) {
|
1087
|
+
CLog(CLogTypes.log, 'onCreateViewHolder', this, this.nativeView, viewType, this.getKeyByValue(viewType), holder, Date.now() - start, 'ms');
|
1088
|
+
}
|
1089
|
+
return holder;
|
1090
|
+
}
|
1091
|
+
notifyForItemAtIndex(eventName, view, index, bindingContext, native) {
|
1092
|
+
const args = { eventName, object: this, index, view, ios: native, bindingContext };
|
1093
|
+
this.notify(args);
|
1094
|
+
return args;
|
1095
|
+
}
|
1096
|
+
onBindViewHolder(holder, position) {
|
1097
|
+
const start = Date.now();
|
1098
|
+
if (Trace.isEnabled()) {
|
1099
|
+
CLog(CLogTypes.log, 'onBindViewHolder', this, this.nativeView, position, holder, holder.view);
|
1100
|
+
}
|
1101
|
+
let view = holder.view;
|
1102
|
+
const isNonSync = holder['defaultItemView'] === true;
|
1103
|
+
view = isNonSync ? view.content : view;
|
1104
|
+
const bindingContext = this._prepareItem(view, position);
|
1105
|
+
if (holder['position'] !== undefined) {
|
1106
|
+
this.bindedViewHolders.delete(holder['position']);
|
1107
|
+
}
|
1108
|
+
holder['position'] = position;
|
1109
|
+
this.bindedViewHolders.add(holder['position']);
|
1110
|
+
const args = this.notifyForItemAtIndex(CollectionViewBase.itemLoadingEvent, view, position, bindingContext, holder);
|
1111
|
+
if (isNonSync && args.view !== view) {
|
1112
|
+
view = args.view;
|
1113
|
+
// the view has been changed on the event handler
|
1114
|
+
holder.view.content = args.view;
|
1115
|
+
}
|
1116
|
+
view.bindingContext = bindingContext;
|
1117
|
+
view.notify({ eventName: CollectionViewBase.bindedEvent });
|
1118
|
+
let width = this._effectiveColWidth;
|
1119
|
+
let height = this._effectiveRowHeight;
|
1120
|
+
if (this._getSpanSize) {
|
1121
|
+
const spanSize = this._getSpanSize(bindingContext, position);
|
1122
|
+
const horizontal = this.isHorizontal();
|
1123
|
+
if (horizontal) {
|
1124
|
+
height *= spanSize;
|
1125
|
+
}
|
1126
|
+
else {
|
1127
|
+
width *= spanSize;
|
1128
|
+
}
|
1129
|
+
}
|
1130
|
+
if (width || !view.width) {
|
1131
|
+
view.width = Utils.layout.toDeviceIndependentPixels(width);
|
1132
|
+
}
|
1133
|
+
if (height || !view.height) {
|
1134
|
+
view.height = Utils.layout.toDeviceIndependentPixels(height);
|
1135
|
+
}
|
1136
|
+
// if (this.hasListeners(CollectionViewBase.displayItemEvent) ) {
|
1137
|
+
// this.notify<CollectionViewItemDisplayEventData>({
|
1138
|
+
// eventName: CollectionViewBase.displayItemEvent,
|
1139
|
+
// index:position,
|
1140
|
+
// object: this,
|
1141
|
+
// });
|
1142
|
+
// }
|
1143
|
+
if (Trace.isEnabled()) {
|
1144
|
+
CLog(CLogTypes.log, 'onBindViewHolder done ', position, Date.now() - start, 'ms');
|
1145
|
+
}
|
1146
|
+
}
|
1147
|
+
onViewRecycled(holder) {
|
1148
|
+
delete this.bindedViewHolders[holder['position']];
|
1149
|
+
holder['position'] = undefined;
|
1150
|
+
}
|
1151
|
+
}
|
1152
|
+
CollectionView.layoutCompletedEvent = 'layoutCompleted';
|
1153
|
+
CollectionView.DEFAULT_TEMPLATE_VIEW_TYPE = 0;
|
1154
|
+
CollectionView.CUSTOM_TEMPLATE_ITEM_TYPE = 1;
|
1155
|
+
__decorate([
|
1156
|
+
profile
|
1157
|
+
], CollectionView.prototype, "createNativeView", null);
|
1158
|
+
__decorate([
|
1159
|
+
profile
|
1160
|
+
], CollectionView.prototype, "initNativeView", null);
|
1161
|
+
__decorate([
|
1162
|
+
profile
|
1163
|
+
], CollectionView.prototype, "disposeNativeView", null);
|
1164
|
+
__decorate([
|
1165
|
+
profile
|
1166
|
+
], CollectionView.prototype, "onLoaded", null);
|
1167
|
+
__decorate([
|
1168
|
+
profile
|
1169
|
+
], CollectionView.prototype, "attachScrollListener", null);
|
1170
|
+
__decorate([
|
1171
|
+
profile
|
1172
|
+
], CollectionView.prototype, "setNativePoolSize", null);
|
1173
|
+
__decorate([
|
1174
|
+
profile
|
1175
|
+
], CollectionView.prototype, "setPoolSizes", null);
|
1176
|
+
__decorate([
|
1177
|
+
profile
|
1178
|
+
], CollectionView.prototype, _a, null);
|
1179
|
+
__decorate([
|
1180
|
+
profile
|
1181
|
+
], CollectionView.prototype, _b, null);
|
1182
|
+
__decorate([
|
1183
|
+
profile
|
1184
|
+
], CollectionView.prototype, "onItemViewLoaderChanged", null);
|
1185
|
+
__decorate([
|
1186
|
+
profile
|
1187
|
+
], CollectionView.prototype, "onItemTemplateSelectorChanged", null);
|
1188
|
+
__decorate([
|
1189
|
+
profile
|
1190
|
+
], CollectionView.prototype, "onItemTemplateChanged", null);
|
1191
|
+
__decorate([
|
1192
|
+
profile
|
1193
|
+
], CollectionView.prototype, "onItemTemplatesChanged", null);
|
1194
|
+
__decorate([
|
1195
|
+
profile
|
1196
|
+
], CollectionView.prototype, "updateSpanCount", null);
|
1197
|
+
__decorate([
|
1198
|
+
profile
|
1199
|
+
], CollectionView.prototype, "updateInnerSize", null);
|
1200
|
+
__decorate([
|
1201
|
+
profile
|
1202
|
+
], CollectionView.prototype, "_onColWidthPropertyChanged", null);
|
1203
|
+
__decorate([
|
1204
|
+
profile
|
1205
|
+
], CollectionView.prototype, "_onRowHeightPropertyChanged", null);
|
1206
|
+
__decorate([
|
1207
|
+
profile
|
1208
|
+
], CollectionView.prototype, "onLayout", null);
|
1209
|
+
__decorate([
|
1210
|
+
profile
|
1211
|
+
], CollectionView.prototype, "onMeasure", null);
|
1212
|
+
__decorate([
|
1213
|
+
profile
|
1214
|
+
], CollectionView.prototype, "refresh", null);
|
1215
|
+
__decorate([
|
1216
|
+
profile
|
1217
|
+
], CollectionView.prototype, "_setPadding", null);
|
1218
|
+
__decorate([
|
1219
|
+
profile
|
1220
|
+
], CollectionView.prototype, "createComposedAdapter", null);
|
1221
|
+
__decorate([
|
1222
|
+
profile
|
1223
|
+
], CollectionView.prototype, "clearTemplateTypes", null);
|
1224
|
+
__decorate([
|
1225
|
+
profile
|
1226
|
+
], CollectionView.prototype, "getItemViewType", null);
|
1227
|
+
__decorate([
|
1228
|
+
profile
|
1229
|
+
], CollectionView.prototype, "templateKeyToNativeItem", null);
|
1230
|
+
__decorate([
|
1231
|
+
profile
|
1232
|
+
], CollectionView.prototype, "disposeViewHolderViews", null);
|
1233
|
+
__decorate([
|
1234
|
+
profile
|
1235
|
+
], CollectionView.prototype, "onCreateViewHolder", null);
|
1236
|
+
__decorate([
|
1237
|
+
profile
|
1238
|
+
], CollectionView.prototype, "notifyForItemAtIndex", null);
|
1239
|
+
__decorate([
|
1240
|
+
profile
|
1241
|
+
], CollectionView.prototype, "onBindViewHolder", null);
|
1242
|
+
let CollectionViewCellHolder;
|
1243
|
+
let CollectionViewRecyclerView;
|
1244
|
+
itemViewCacheSizeProperty.register(CollectionViewBase);
|
1245
|
+
extraLayoutSpaceProperty.register(CollectionViewBase);
|
1246
|
+
nestedScrollingEnabledProperty.register(CollectionViewBase);
|
1247
|
+
//# sourceMappingURL=index.android.js.map
|