|
7 | 7 |
|
8 | 8 | package com.facebook.react.views.scroll;
|
9 | 9 |
|
| 10 | +import static com.facebook.react.views.scroll.ReactScrollViewHelper.SNAP_ALIGNMENT_CENTER; |
10 | 11 | import static com.facebook.react.views.scroll.ReactScrollViewHelper.SNAP_ALIGNMENT_DISABLED;
|
| 12 | +import static com.facebook.react.views.scroll.ReactScrollViewHelper.SNAP_ALIGNMENT_END; |
| 13 | +import static com.facebook.react.views.scroll.ReactScrollViewHelper.SNAP_ALIGNMENT_START; |
11 | 14 |
|
12 | 15 | import android.animation.Animator;
|
13 | 16 | import android.animation.ObjectAnimator;
|
@@ -641,6 +644,10 @@ private int predictFinalScrollPosition(int velocityY) {
|
641 | 644 | return scroller.getFinalY();
|
642 | 645 | }
|
643 | 646 |
|
| 647 | + private View getContentView() { |
| 648 | + return getChildAt(0); |
| 649 | + } |
| 650 | + |
644 | 651 | /**
|
645 | 652 | * This will smooth scroll us to the nearest snap offset point It currently just looks at where
|
646 | 653 | * the content is and slides to the nearest point. It is intended to be run after we are done
|
@@ -697,7 +704,7 @@ private void flingAndSnap(int velocityY) {
|
697 | 704 | }
|
698 | 705 |
|
699 | 706 | // pagingEnabled only allows snapping one interval at a time
|
700 |
| - if (mSnapInterval == 0 && mSnapOffsets == null) { |
| 707 | + if (mSnapInterval == 0 && mSnapOffsets == null && mSnapToAlignment == SNAP_ALIGNMENT_DISABLED) { |
701 | 708 | smoothScrollAndSnap(velocityY);
|
702 | 709 | return;
|
703 | 710 | }
|
@@ -734,6 +741,37 @@ private void flingAndSnap(int velocityY) {
|
734 | 741 | }
|
735 | 742 | }
|
736 | 743 | }
|
| 744 | + |
| 745 | + } else if (mSnapToAlignment != SNAP_ALIGNMENT_DISABLED) { |
| 746 | + ViewGroup contentView = (ViewGroup) getContentView(); |
| 747 | + for (int i = 1; i < contentView.getChildCount(); i++) { |
| 748 | + View item = contentView.getChildAt(i); |
| 749 | + int itemStartOffset; |
| 750 | + switch (mSnapToAlignment) { |
| 751 | + case SNAP_ALIGNMENT_CENTER: |
| 752 | + itemStartOffset = item.getTop() - (height - item.getHeight()) / 2; |
| 753 | + break; |
| 754 | + case SNAP_ALIGNMENT_START: |
| 755 | + itemStartOffset = item.getTop(); |
| 756 | + break; |
| 757 | + case SNAP_ALIGNMENT_END: |
| 758 | + itemStartOffset = item.getTop() - (height - item.getHeight()); |
| 759 | + break; |
| 760 | + default: |
| 761 | + throw new IllegalStateException("Invalid SnapToAlignment value: " + mSnapToAlignment); |
| 762 | + } |
| 763 | + if (itemStartOffset <= targetOffset) { |
| 764 | + if (targetOffset - itemStartOffset < targetOffset - smallerOffset) { |
| 765 | + smallerOffset = itemStartOffset; |
| 766 | + } |
| 767 | + } |
| 768 | + |
| 769 | + if (itemStartOffset >= targetOffset) { |
| 770 | + if (itemStartOffset - targetOffset < largerOffset - targetOffset) { |
| 771 | + largerOffset = itemStartOffset; |
| 772 | + } |
| 773 | + } |
| 774 | + } |
737 | 775 | } else {
|
738 | 776 | double interval = (double) getSnapInterval();
|
739 | 777 | double ratio = (double) targetOffset / interval;
|
|
0 commit comments