import { View , KeyedTemplate , Property , Length , unsetValue , booleanConverter } from "ui/core/view" ; import { addWeakEventListener } from "ui/core/weak-event-listener" ; import { ListView , ItemsSource } from "ui/list-view" ; import { layout } from "utils/utils" ; import { RecyclerViewBase , ItemEventData } from "./recycler-view.common" ; export * from "./recycler-view.common" ; export class RecyclerView extends RecyclerViewBase { private clickListener ; private _androidViewId : number = - 1 ; get recycler ( ) : android . support . v7 . widget . RecyclerView { return this . nativeView ; } scrollToIndex ( index ) { if ( ! this . recycler ) { return ; } this . recycler . scrollToPosition ( index ) ; } refresh ( ) { if ( ! this . recycler || ! this . recycler . getAdapter ( ) ) { return ; } this . recycler . getAdapter ( ) . notifyDataSetChanged ( ) ; } createNativeView ( ) { const recycler = new android . support . v7 . widget . RecyclerView ( this . _context ) ; const packVG = android . view . ViewGroup ; let layoutManager = new android . support . v7 . widget . LinearLayoutManager ( this . _context ) ; recycler . setLayoutManager ( layoutManager ) ; recycler . setLayoutParams ( new packVG . LayoutParams ( packVG . LayoutParams . MATCH_PARENT , packVG . LayoutParams . MATCH_PARENT ) ) ; return recycler ; } initNativeView ( ) { super . initNativeView ( ) ; ensureRecyclerViewListAdapterClass ( ) ; const adapter = new RecyclerViewListAdapterClass ( new WeakRef ( this ) ) ; ensureClickListenerClass ( ) ; const self = this ; this . clickListener = new RecyclerItemClickListener ( this . _context , this . recycler , { onItemClick ( view , index ) { self . notify ( { eventName : ListView . itemTapEvent , object : this , index , view } ) ; } , onLongItemClick ( view , index ) { self . notify ( { eventName : RecyclerViewBase . itemLongTapEvent , object : this , index , view } ) ; } } ) ; this . recycler . addOnItemTouchListener ( this . clickListener ) ; this . recycler . setAdapter ( adapter ) ; if ( this . _androidViewId < 0 ) { this . _androidViewId = android . view . View . generateViewId ( ) ; } this . recycler . setId ( this . _androidViewId ) ; } disposeNativeView ( ) { this . recycler . setAdapter ( null ) ; this . recycler . removeOnItemTouchListener ( this . clickListener ) ; super . disposeNativeView ( ) ; } } /**
 * CLICK LISTENER
 */ interface OnItemClickListener { onItemClick ( view , position ) ; onLongItemClick ( view , position ) ; } let RecyclerItemClickListener = null ; function ensureClickListenerClass ( ) { if ( RecyclerItemClickListener ) { return RecyclerItemClickListener ; } class SimpleGestureImpl extends android . view . GestureDetector . SimpleOnGestureListener { constructor ( private recyclerItem ) { super ( ) ; return global . __native ( this ) ; } onSingleTapUp ( e ) { return true ; } onLongPress ( e ) { let child = this . recyclerItem . recyclerView . findChildViewUnder ( e . getX ( ) , e . getY ( ) ) ; if ( child != null && this . recyclerItem . listener != null ) { this . recyclerItem . listener . onLongItemClick ( child , this . recyclerItem . recyclerView . getChildAdapterPosition ( child ) ) ; } } } @ Interfaces ( [ android . support . v7 . widget . RecyclerView . OnItemTouchListener ] ) class RecyclerItemClickListenerImpl extends java . lang . Object implements android . support . v7 . widget . RecyclerView . OnItemTouchListener { mGestureDetector : android . view . GestureDetector ; constructor ( context , public recyclerView , public listener ) { super ( ) ; this . mGestureDetector = new android . view . GestureDetector ( context , new SimpleGestureImpl ( this ) ) ; return global . __native ( this ) ; } onInterceptTouchEvent ( view , e ) { let childView = view . findChildViewUnder ( e . getX ( ) , e . getY ( ) ) ; if ( childView != null && this . listener != null && this . mGestureDetector . onTouchEvent ( e ) ) { this . listener . onItemClick ( childView , view . getChildAdapterPosition ( childView ) ) ; return true ; } return false ; } onTouchEvent ( view , motionEvent ) { } onRequestDisallowInterceptTouchEvent ( disallowIntercept ) { } } RecyclerItemClickListener = RecyclerItemClickListenerImpl ; return RecyclerItemClickListener ; } /**
 * CROSS VIEW HOLDER
 */ interface CrossViewHolderType extends android . support . v7 . widget . RecyclerView . ViewHolder { view : View ; } let CrossViewHolderClass ; function ensureCrossViewHolderClass ( ) { if ( CrossViewHolderClass ) { return ; } class CrossViewHolder extends android . support . v7 . widget . RecyclerView . ViewHolder { constructor ( public view ) { super ( view . nativeView ) ; return global . __native ( this ) ; } } CrossViewHolderClass = CrossViewHolder ; } /**
 * ADAPTER
 */ let RecyclerViewListAdapterClass ; export function ensureRecyclerViewListAdapterClass ( ) { if ( RecyclerViewListAdapterClass ) { return RecyclerViewListAdapterClass ; } class RecyclerViewListAdapter extends android . support . v7 . widget . RecyclerView . Adapter { nbCreated = 0 ; constructor ( private ownerRef ) { super ( ) ; return global . __native ( this ) ; } getItemViewType ( position ) { return this . owner ? this . owner . getTemplateIdForItemAt ( position ) : 0 ; } onCreateViewHolder ( parent , viewType ) { if ( ! this . owner ) { return null ; } this . nbCreated ++ ; let template = this . owner . getTemplateForTypeId ( viewType ) ; let view = template . createView ( ) ; this . owner . _addView ( view ) ; if ( ! view ) { throw "View should be initialized!" ; } let layoutParams = new android . support . v7 . widget . RecyclerView . LayoutParams ( android . view . ViewGroup . LayoutParams . MATCH_PARENT , android . view . ViewGroup . LayoutParams . WRAP_CONTENT ) ; view . android . setLayoutParams ( layoutParams ) ; ensureCrossViewHolderClass ( ) ; return new CrossViewHolderClass ( view ) ; } onBindViewHolder ( viewHolder , position ) { if ( ! this . owner ) { return ; } const real = < CrossViewHolderType > viewHolder ; let totalItemCount = this . owner . items ? this . owner . items . length : 0 ; if ( position === ( totalItemCount - 1 ) ) { this . owner . notify ( { eventName : RecyclerView . loadMoreItemsEvent , object : this . owner } ) ; } let args = { eventName : RecyclerView . itemLoadingEvent , object : this . owner , index : position , android : real . view . nativeView , view : real . view , ios : undefined } ; this . owner . notify ( args ) ; if ( this . owner . _effectiveRowHeight > - 1 ) { real . view . height = this . owner . rowHeight ; } else { real . view . height = < Length > unsetValue ; } try { real . view . bindingContext = this . owner . _getDataItem ( position ) ; } catch ( e ) { console . error ( "Failed to bind context:" , e ) ; } } get owner ( ) { return this . ownerRef ? this . ownerRef . get ( ) : null ; } getItemCount ( ) { return this . ownerRef ? this . owner . items . length : 0 ; } } RecyclerViewListAdapterClass = RecyclerViewListAdapter ; return RecyclerViewListAdapterClass ; }