recyclerview-selection/src/main/java/androidx/recyclerview/selection/SelectionTracker.java
public SelectionTracker<K> build() {

            SelectionTracker<K> tracker = new DefaultSelectionTracker<>(
                    mSelectionId, mKeyProvider, mSelectionPredicate, mStorage);

            // Event glue between RecyclerView and SelectionTracker keeps the classes separate
            // so that a SelectionTracker can be shared across RecyclerView instances that
            // represent the same data in different ways.
            EventBridge.install(mAdapter, tracker, mKeyProvider);

            AutoScroller scroller =
                    new ViewAutoScroller(ViewAutoScroller.createScrollHost(mRecyclerView));

            // Setup basic input handling, with the touch handler as the default consumer
            // of events. If mouse handling is configured as well, the mouse input
            // related handlers will intercept mouse input events.

            // GestureRouter is responsible for routing GestureDetector events
            // to tool-type specific handlers.
            GestureRouter<MotionInputHandler> gestureRouter = new GestureRouter<>();
            GestureDetector gestureDetector = new GestureDetector(mContext, gestureRouter);

            // TouchEventRouter takes its name from RecyclerView#OnItemTouchListener.
            // Despite "Touch" being in the name, it receives events for all types of tools.
            // This class is responsible for routing events to tool-type specific handlers,
            // and if not handled by a handler, on to a GestureDetector for analysis.
            TouchEventRouter eventRouter = new TouchEventRouter(gestureDetector);

            // GestureSelectionHelper provides logic that interprets a combination
            // of motions and gestures in order to provide gesture driven selection support
            // when used in conjunction with RecyclerView.
            final GestureSelectionHelper gestureHelper =
                    GestureSelectionHelper.create(tracker, mRecyclerView, scroller, mMonitor);

            // Finally hook the framework up to listening to recycle view events.
            mRecyclerView.addOnItemTouchListener(eventRouter);

            // But before you move on, there's more work to do. Event plumbing has been
            // installed, but we haven't registered any of our helpers or callbacks.
            // Helpers contain predefined logic converting events into selection related events.
            // Callbacks provide developers the ability to reponspond to other types of
            // events (like "activate" a tapped item). This is broken up into two main
            // suites, one for "touch" and one for "mouse", though both can and should (usually)
            // be configured to handle other types of input (to satisfy user expectation).);

            // Internally, the code doesn't permit nullable listeners, so we lazily
            // initialize dummy instances if the developer didn't supply a real listener.
            mOnDragInitiatedListener = (mOnDragInitiatedListener != null)
                    ? mOnDragInitiatedListener
                    : new OnDragInitiatedListener() {
                        @Override
                        public boolean onDragInitiated(@NonNull MotionEvent e) {
                            return false;
                        }
                    };

            mOnItemActivatedListener = (mOnItemActivatedListener != null)
                    ? mOnItemActivatedListener
                    : new OnItemActivatedListener<K>() {
                        @Override
                        public boolean onItemActivated(
                                @NonNull ItemDetailsLookup.ItemDetails<K> item,
                                @NonNull MotionEvent e) {
                            return false;
                        }
                    };

            mOnContextClickListener = (mOnContextClickListener != null)
                    ? mOnContextClickListener
                    : new OnContextClickListener() {
                        @Override
                        public boolean onContextClick(@NonNull MotionEvent e) {
                            return false;
                        }
                    };

            // Provides high level glue for binding touch events
            // and gestures to selection framework.
            TouchInputHandler<K> touchHandler = new TouchInputHandler<K>(
                    tracker,
                    mKeyProvider,
                    mDetailsLookup,
                    mSelectionPredicate,
                    new Runnable() {
                        @Override
                        public void run() {
                            if (mSelectionPredicate.canSelectMultiple()) {
                                gestureHelper.start();
                            }
                        }
                    },
                    mOnDragInitiatedListener,
                    mOnItemActivatedListener,
                    mFocusDelegate,
                    new Runnable() {
                        @Override
                        public void run() {
                            mRecyclerView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
                        }
                    });

            for (int toolType : mGestureToolTypes) {
                gestureRouter.register(toolType, touchHandler);
                eventRouter.register(toolType, gestureHelper);
            }

            // Provides high level glue for binding mouse events and gestures
            // to selection framework.
            MouseInputHandler<K> mouseHandler = new MouseInputHandler<>(
                    tracker,
                    mKeyProvider,
                    mDetailsLookup,
                    mOnContextClickListener,
                    mOnItemActivatedListener,
                    mFocusDelegate);

            for (int toolType : mPointerToolTypes) {
                gestureRouter.register(toolType, mouseHandler);
            }

            @Nullable BandSelectionHelper bandHelper = null;

            // Band selection not supported in single select mode, or when key access
            // is limited to anything less than the entire corpus.
            if (mKeyProvider.hasAccess(ItemKeyProvider.SCOPE_MAPPED)
                    && mSelectionPredicate.canSelectMultiple()) {
                // BandSelectionHelper provides support for band selection on-top of a RecyclerView
                // instance. Given the recycling nature of RecyclerView BandSelectionController
                // necessarily models and caches list/grid information as the user's pointer
                // interacts with the item in the RecyclerView. Selectable items that intersect
                // with the band, both on and off screen, are selected.
                bandHelper = BandSelectionHelper.create(
                        mRecyclerView,
                        scroller,
                        mBandOverlayId,
                        mKeyProvider,
                        tracker,
                        mSelectionPredicate,
                        mBandPredicate,
                        mFocusDelegate,
                        mMonitor);
            }

            OnItemTouchListener pointerEventHandler = new PointerDragEventInterceptor(
                    mDetailsLookup, mOnDragInitiatedListener, bandHelper);

            for (int toolType : mPointerToolTypes) {
                eventRouter.register(toolType, pointerEventHandler);
            }

            return tracker;
        }
/**
         * Prepares and returns a SelectionTracker.
         *
         * @return this
         */
Prepares and returns a SelectionTracker.
@return this
Prepares and returns a SelectionTracker . @return this
public SelectionTracker<K> build() {
            SelectionTracker<K> tracker = new DefaultSelectionTracker<>(
                    mSelectionId, mKeyProvider, mSelectionPredicate, mStorage);
            EventBridge.install(mAdapter, tracker, mKeyProvider);
            AutoScroller scroller =
                    new ViewAutoScroller(ViewAutoScroller.createScrollHost(mRecyclerView));
            GestureRouter<MotionInputHandler> gestureRouter = new GestureRouter<>();
            GestureDetector gestureDetector = new GestureDetector(mContext, gestureRouter);
            TouchEventRouter eventRouter = new TouchEventRouter(gestureDetector);
            final GestureSelectionHelper gestureHelper =
                    GestureSelectionHelper.create(tracker, mRecyclerView, scroller, mMonitor);
            mRecyclerView.addOnItemTouchListener(eventRouter);
            mOnDragInitiatedListener = (mOnDragInitiatedListener != null)
                    ? mOnDragInitiatedListener
                    : new OnDragInitiatedListener() {
                        @Override
                        public boolean onDragInitiated(@NonNull MotionEvent e) {
                            return false;
                        }
                    };
            mOnItemActivatedListener = (mOnItemActivatedListener != null)
                    ? mOnItemActivatedListener
                    : new OnItemActivatedListener<K>() {
                        @Override
                        public boolean onItemActivated(
                                @NonNull ItemDetailsLookup.ItemDetails<K> item,
                                @NonNull MotionEvent e) {
                            return false;
                        }
                    };
            mOnContextClickListener = (mOnContextClickListener != null)
                    ? mOnContextClickListener
                    : new OnContextClickListener() {
                        @Override
                        public boolean onContextClick(@NonNull MotionEvent e) {
                            return false;
                        }
                    };
            TouchInputHandler<K> touchHandler = new TouchInputHandler<K>(
                    tracker,
                    mKeyProvider,
                    mDetailsLookup,
                    mSelectionPredicate,
                    new Runnable() {
                        @Override
                        public void run() {
                            if (mSelectionPredicate.canSelectMultiple()) {
                                gestureHelper.start();
                            }
                        }
                    },
                    mOnDragInitiatedListener,
                    mOnItemActivatedListener,
                    mFocusDelegate,
                    new Runnable() {
                        @Override
                        public void run() {
                            mRecyclerView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
                        }
                    });
            for (int toolType : mGestureToolTypes) {
                gestureRouter.register(toolType, touchHandler);
                eventRouter.register(toolType, gestureHelper);
            }
            MouseInputHandler<K> mouseHandler = new MouseInputHandler<>(
                    tracker,
                    mKeyProvider,
                    mDetailsLookup,
                    mOnContextClickListener,
                    mOnItemActivatedListener,
                    mFocusDelegate);
            for (int toolType : mPointerToolTypes) {
                gestureRouter.register(toolType, mouseHandler);
            }
            @Nullable BandSelectionHelper bandHelper = null;
            if (mKeyProvider.hasAccess(ItemKeyProvider.SCOPE_MAPPED)
                    && mSelectionPredicate.canSelectMultiple()) {
                bandHelper = BandSelectionHelper.create(
                        mRecyclerView,
                        scroller,
                        mBandOverlayId,
                        mKeyProvider,
                        tracker,
                        mSelectionPredicate,
                        mBandPredicate,
                        mFocusDelegate,
                        mMonitor);
            }
            OnItemTouchListener pointerEventHandler = new PointerDragEventInterceptor(
                    mDetailsLookup, mOnDragInitiatedListener, bandHelper);
            for (int toolType : mPointerToolTypes) {
                eventRouter.register(toolType, pointerEventHandler);
            }
            return tracker;
        }
public SelectionTracker < K > build ( ) { SelectionTracker < K > tracker = new DefaultSelectionTracker < > ( mSelectionId , mKeyProvider , mSelectionPredicate , mStorage ) ; EventBridge . install ( mAdapter , tracker , mKeyProvider ) ; AutoScroller scroller = new ViewAutoScroller ( ViewAutoScroller . createScrollHost ( mRecyclerView ) ) ; GestureRouter < MotionInputHandler > gestureRouter = new GestureRouter < > ( ) ; GestureDetector gestureDetector = new GestureDetector ( mContext , gestureRouter ) ; TouchEventRouter eventRouter = new TouchEventRouter ( gestureDetector ) ; final GestureSelectionHelper gestureHelper = GestureSelectionHelper . create ( tracker , mRecyclerView , scroller , mMonitor ) ; mRecyclerView . addOnItemTouchListener ( eventRouter ) ; mOnDragInitiatedListener = ( mOnDragInitiatedListener != null ) ? mOnDragInitiatedListener : new OnDragInitiatedListener ( ) { @ Override public boolean onDragInitiated ( @ NonNull MotionEvent e ) { return false ; } } ; mOnItemActivatedListener = ( mOnItemActivatedListener != null ) ? mOnItemActivatedListener : new OnItemActivatedListener < K > ( ) { @ Override public boolean onItemActivated ( @ NonNull ItemDetailsLookup . ItemDetails < K > item , @ NonNull MotionEvent e ) { return false ; } } ; mOnContextClickListener = ( mOnContextClickListener != null ) ? mOnContextClickListener : new OnContextClickListener ( ) { @ Override public boolean onContextClick ( @ NonNull MotionEvent e ) { return false ; } } ; TouchInputHandler < K > touchHandler = new TouchInputHandler < K > ( tracker , mKeyProvider , mDetailsLookup , mSelectionPredicate , new Runnable ( ) { @ Override public void run ( ) { if ( mSelectionPredicate . canSelectMultiple ( ) ) { gestureHelper . start ( ) ; } } } , mOnDragInitiatedListener , mOnItemActivatedListener , mFocusDelegate , new Runnable ( ) { @ Override public void run ( ) { mRecyclerView . performHapticFeedback ( HapticFeedbackConstants . LONG_PRESS ) ; } } ) ; for ( int toolType : mGestureToolTypes ) { gestureRouter . register ( toolType , touchHandler ) ; eventRouter . register ( toolType , gestureHelper ) ; } MouseInputHandler < K > mouseHandler = new MouseInputHandler < > ( tracker , mKeyProvider , mDetailsLookup , mOnContextClickListener , mOnItemActivatedListener , mFocusDelegate ) ; for ( int toolType : mPointerToolTypes ) { gestureRouter . register ( toolType , mouseHandler ) ; } @ Nullable BandSelectionHelper bandHelper = null ; if ( mKeyProvider . hasAccess ( ItemKeyProvider . SCOPE_MAPPED ) && mSelectionPredicate . canSelectMultiple ( ) ) { bandHelper = BandSelectionHelper . create ( mRecyclerView , scroller , mBandOverlayId , mKeyProvider , tracker , mSelectionPredicate , mBandPredicate , mFocusDelegate , mMonitor ) ; } OnItemTouchListener pointerEventHandler = new PointerDragEventInterceptor ( mDetailsLookup , mOnDragInitiatedListener , bandHelper ) ; for ( int toolType : mPointerToolTypes ) { eventRouter . register ( toolType , pointerEventHandler ) ; } return tracker ; }
Prepares and returns a SelectionTracker.
Prepares and returns a SelectionTracker .
// Event glue between RecyclerView and SelectionTracker keeps the classes separate // so that a SelectionTracker can be shared across RecyclerView instances that // represent the same data in different ways. // Setup basic input handling, with the touch handler as the default consumer // of events. If mouse handling is configured as well, the mouse input // related handlers will intercept mouse input events. // GestureRouter is responsible for routing GestureDetector events // to tool-type specific handlers. // TouchEventRouter takes its name from RecyclerView#OnItemTouchListener. // Despite "Touch" being in the name, it receives events for all types of tools. // This class is responsible for routing events to tool-type specific handlers, // and if not handled by a handler, on to a GestureDetector for analysis. // GestureSelectionHelper provides logic that interprets a combination // of motions and gestures in order to provide gesture driven selection support // when used in conjunction with RecyclerView. // Finally hook the framework up to listening to recycle view events. // But before you move on, there's more work to do. Event plumbing has been // installed, but we haven't registered any of our helpers or callbacks. // Helpers contain predefined logic converting events into selection related events. // Callbacks provide developers the ability to reponspond to other types of // events (like "activate" a tapped item). This is broken up into two main // suites, one for "touch" and one for "mouse", though both can and should (usually) // be configured to handle other types of input (to satisfy user expectation).); // Internally, the code doesn't permit nullable listeners, so we lazily // initialize dummy instances if the developer didn't supply a real listener. // Provides high level glue for binding touch events // and gestures to selection framework. // Provides high level glue for binding mouse events and gestures // to selection framework. // Band selection not supported in single select mode, or when key access // is limited to anything less than the entire corpus. // BandSelectionHelper provides support for band selection on-top of a RecyclerView // instance. Given the recycling nature of RecyclerView BandSelectionController // necessarily models and caches list/grid information as the user's pointer // interacts with the item in the RecyclerView. Selectable items that intersect // with the band, both on and off screen, are selected.