@@ -15,11 +15,92 @@ import {
1515 profile ,
1616} from '@nativescript/core' ;
1717import { layout } from '@nativescript/core/utils/utils' ;
18- import { CollectionViewItemEventData , Orientation , reverseLayoutProperty } from './collectionview' ;
18+ import { CollectionViewItemDisplayEventData , CollectionViewItemEventData , Orientation , reorderingEnabledProperty , reverseLayoutProperty } from './collectionview' ;
1919import { CLog , CLogTypes , CollectionViewBase , ListViewViewTypes , isScrollEnabledProperty , orientationProperty } from './collectionview-common' ;
2020
2121export * from './collectionview-common' ;
2222
23+ declare module '@nativescript/core/ui/core/view' {
24+ interface View {
25+ handleGestureTouch ( event : android . view . MotionEvent ) ;
26+ }
27+ }
28+
29+
30+ @NativeClass
31+ class SimpleCallback extends androidx . recyclerview . widget . ItemTouchHelper . SimpleCallback {
32+ owner : WeakRef < CollectionView > ;
33+ constructor ( param1 : number , param2 : number ) {
34+ super ( param1 , param2 ) ;
35+ return global . __native ( this ) ;
36+ }
37+ onMove ( recyclerview : androidx . recyclerview . widget . RecyclerView , viewHolder : androidx . recyclerview . widget . RecyclerView . ViewHolder , target : androidx . recyclerview . widget . RecyclerView . ViewHolder ) : boolean {
38+ const startPosition = viewHolder . getAdapterPosition ( ) ;
39+ const endPosition = target . getAdapterPosition ( ) ;
40+ if ( this . startPosition === - 1 ) {
41+ this . startPosition = startPosition ;
42+ }
43+ this . endPosition = endPosition ;
44+ const owner = this . owner && this . owner . get ( ) ;
45+ if ( owner ) {
46+ owner . _reorderItemInSource ( startPosition , endPosition ) ;
47+ return true ;
48+ }
49+ return false ;
50+ }
51+ startPosition = - 1 ;
52+ endPosition = - 1 ;
53+ onSelectedChanged ( viewHolder : androidx . recyclerview . widget . RecyclerView . ViewHolder , state : number ) {
54+ console . log ( 'onSelectedChanged' , viewHolder , this . startPosition , this . endPosition ) ;
55+ if ( viewHolder ) {
56+ if ( this . startPosition === - 1 ) {
57+ this . startPosition = viewHolder . getAdapterPosition ( ) ;
58+ }
59+ }
60+ if ( ! viewHolder ) {
61+ // this is where we identify the end of the drag and call the end event
62+ const owner = this . owner && this . owner . get ( ) ;
63+
64+ if ( this . endPosition === - 1 ) {
65+ this . endPosition = this . startPosition ;
66+ }
67+ if ( owner ) {
68+ const item = owner . getItemAtIndex ( this . startPosition ) ;
69+ owner . _callItemReorderedEvent ( this . startPosition , this . endPosition , item ) ;
70+ }
71+ this . startPosition = - 1 ;
72+ this . endPosition = - 1 ;
73+ owner . isDragging = false ;
74+ }
75+ }
76+ onSwiped ( viewHolder : androidx . recyclerview . widget . RecyclerView . ViewHolder ,
77+ direction : number ) {
78+ }
79+ isItemViewSwipeEnabled ( ) {
80+ // disabled for now
81+ return false ;
82+ }
83+ isLongPressDragEnabled ( ) {
84+ // we use our custom longpress gesture handler
85+ return false ;
86+ }
87+ }
88+
89+
90+ @NativeClass
91+ class LongPressGestureListenerImpl extends android . view . GestureDetector . SimpleOnGestureListener {
92+ constructor ( private _owner : WeakRef < CollectionView > ) {
93+ super ( ) ;
94+ return global . __native ( this ) ;
95+ }
96+ public onLongPress ( motionEvent : android . view . MotionEvent ) : void {
97+ const owner = this . _owner && this . _owner . get ( ) ;
98+ if ( owner ) {
99+ owner . onReorderLongPress ( motionEvent ) ;
100+ }
101+ }
102+
103+ }
23104
24105// @NativeClass
25106// class PreCachingGridLayoutManager extends com.nativescript.collectionview.PreCachingGridLayoutManager {
@@ -127,6 +208,10 @@ export class CollectionView extends CollectionViewBase {
127208
128209 private _listViewAdapter : com . nativescript . collectionview . Adapter ;
129210
211+ // reordering
212+ private _simpleItemTouchCallback : SimpleCallback ;
213+ private _itemTouchHelper : androidx . recyclerview . widget . ItemTouchHelper ;
214+
130215 @profile
131216 public createNativeView ( ) {
132217 // storing the class in a property for reuse in the future cause a materializing which is pretty slow!
@@ -187,7 +272,19 @@ export class CollectionView extends CollectionViewBase {
187272 // rowHeightProperty.coerce(this);
188273 }
189274 _getSpanSize : ( position : number ) => number ;
275+ public getViewForItemAtIndex ( index : number ) : View {
190276
277+ let result : View ;
278+ this . _viewHolders . some ( function ( cellItemView , key ) {
279+ if ( cellItemView && cellItemView . getAdapterPosition ( ) === index ) {
280+ result = cellItemView . view ;
281+ return true ;
282+ }
283+ return false ;
284+ } ) ;
285+
286+ return result ;
287+ }
191288 //@ts -ignore
192289 set spanSize ( inter : ( position : number ) => number ) {
193290 if ( ! ( typeof inter === 'function' ) ) {
@@ -236,6 +333,7 @@ export class CollectionView extends CollectionViewBase {
236333 if ( nativeView . scrollListener ) {
237334 this . nativeView . removeOnScrollListener ( nativeView . scrollListener ) ;
238335 nativeView . scrollListener = null ;
336+ this . _nScrollListener = null ;
239337 }
240338 }
241339 }
@@ -305,19 +403,26 @@ export class CollectionView extends CollectionViewBase {
305403
306404 public disposeNativeView ( ) {
307405 // clear the cache
308- this . eachChildView ( ( view ) => {
309- view . parent . _removeView ( view ) ;
310- return true ;
311- } ) ;
406+ // this.eachChildView((view) => {
407+ // view.parent._removeView(view);
408+ // return true;
409+ // });
312410 // this._realizedItems.clear();
313411
314412 const nativeView = this . nativeView ;
315-
316413 if ( nativeView . scrollListener ) {
317414 this . nativeView . removeOnScrollListener ( nativeView . scrollListener ) ;
318415 nativeView . scrollListener = null ;
416+ this . _nScrollListener = null ;
319417 }
320418 nativeView . layoutManager = null ;
419+ this . _listViewAdapter = null ;
420+ this . _itemTouchHelper = null ;
421+ this . _simpleItemTouchCallback = null ;
422+ this . disposeViewHolderViews ( ) ;
423+ this . _hlayoutParams = null ;
424+ this . _vlayoutParams = null ;
425+ this . clearTemplateTypes ( ) ;
321426
322427 super . disposeNativeView ( ) ;
323428 }
@@ -416,6 +521,79 @@ export class CollectionView extends CollectionViewBase {
416521 public [ itemViewCacheSizeProperty . setNative ] ( value : number ) {
417522 this . nativeViewProtected . setItemViewCacheSize ( value ) ;
418523 }
524+ public startDragging ( index : number ) {
525+ if ( this . reorderEnabled && this . _itemTouchHelper ) {
526+ let viewHolder : CollectionViewCellHolder ;
527+ this . _viewHolders . some ( ( v ) => {
528+ if ( v . getAdapterPosition ( ) === index ) {
529+ viewHolder = v ;
530+ return true ;
531+ }
532+ return false ;
533+ } ) ;
534+ if ( viewHolder ) {
535+ this . startViewHolderDragging ( index , viewHolder ) ;
536+ }
537+ }
538+ }
539+ isDragging = false ;
540+ startViewHolderDragging ( index , viewHolder : CollectionViewCellHolder ) {
541+ // isDragging is to prevent longPress from triggering and starting a new drag
542+ // when triggered manually
543+ if ( ! this . isDragging && this . shouldMoveItemAtIndex ( index ) ) {
544+ this . isDragging = true ;
545+ this . _itemTouchHelper . startDrag ( viewHolder ) ;
546+ }
547+ }
548+ onReorderLongPress ( motionEvent : android . view . MotionEvent ) {
549+ const collectionView = this . nativeViewProtected ;
550+ if ( ! collectionView ) {
551+ return ;
552+ }
553+ const view = collectionView . findChildViewUnder ( motionEvent . getX ( ) , motionEvent . getY ( ) ) ;
554+ const viewHolder = view != null ? collectionView . getChildViewHolder ( view ) : null ;
555+ if ( viewHolder ) {
556+ this . startViewHolderDragging ( viewHolder . getAdapterPosition ( ) , viewHolder as CollectionViewCellHolder ) ;
557+ }
558+ }
559+ _reorderItemInSource ( oldPosition : number , newPosition : number ) {
560+ const adapter = this . _listViewAdapter ;
561+ // 3. Tell adapter to render the model update.
562+ adapter . notifyItemMoved ( oldPosition , newPosition ) ;
563+ // on android _reorderItemInSource is call on every "move" and needs to update the adapter/items
564+ // we will call events only at then end
565+ super . _reorderItemInSource ( oldPosition , newPosition , false ) ;
566+ }
567+
568+ _longPressGesture : androidx . core . view . GestureDetectorCompat ;
569+ _itemTouchListerner : androidx . recyclerview . widget . RecyclerView . OnItemTouchListener ;
570+ public [ reorderingEnabledProperty . setNative ] ( value : boolean ) {
571+ if ( value ) {
572+ if ( ! this . _simpleItemTouchCallback ) {
573+ const ItemTouchHelper = androidx . recyclerview . widget . ItemTouchHelper ;
574+ this . _simpleItemTouchCallback = new SimpleCallback ( ItemTouchHelper . UP | ItemTouchHelper . DOWN | ItemTouchHelper . START | ItemTouchHelper . END , 0 ) ;
575+ this . _simpleItemTouchCallback . owner = new WeakRef ( this ) ;
576+ this . _itemTouchHelper = new androidx . recyclerview . widget . ItemTouchHelper ( this . _simpleItemTouchCallback ) ;
577+ this . _itemTouchHelper . attachToRecyclerView ( this . nativeViewProtected ) ;
578+ }
579+ if ( ! this . _longPressGesture ) {
580+ this . _longPressGesture = new androidx . core . view . GestureDetectorCompat ( this . _context , new LongPressGestureListenerImpl ( new WeakRef ( this ) ) ) ;
581+ this . _itemTouchListerner = new androidx . recyclerview . widget . RecyclerView . OnItemTouchListener ( {
582+ onInterceptTouchEvent :( view : android . view . View , event : android . view . MotionEvent ) => {
583+ if ( this . reorderEnabled && this . _longPressGesture ) {
584+ this . _longPressGesture . onTouchEvent ( event ) ;
585+ }
586+ return false ;
587+ } ,
588+ onTouchEvent :( param0 : androidx . recyclerview . widget . RecyclerView , param1 : globalAndroid . view . MotionEvent ) => {
589+ } ,
590+ onRequestDisallowInterceptTouchEvent :( disallowIntercept : boolean ) => {
591+ }
592+ } ) ;
593+ this . nativeViewProtected . addOnItemTouchListener ( this . _itemTouchListerner ) ;
594+ }
595+ }
596+ }
419597
420598 onItemViewLoaderChanged ( ) {
421599 if ( this . itemViewLoader ) {
@@ -675,6 +853,7 @@ export class CollectionView extends CollectionViewBase {
675853 } ) ;
676854 this . _viewHolders = new Array ( ) ;
677855 this . _viewHolderChildren . forEach ( this . _removeViewCore ) ;
856+ this . _viewHolderChildren = new Array ( ) ;
678857 }
679858 getKeyByValue ( viewType : number ) {
680859 return this . templateStringTypeNumber . get ( viewType ) ;
0 commit comments