Tuyên bố từ chối trách nhiệm: những gì tiếp theo chủ yếu là kết quả của thử nghiệm của riêng tôi trong React Native 0.50. Các ScrollViewtài liệu hiện đang thiếu rất nhiều thông tin đề cập dưới đây; chẳng hạn onScrollEndDraglà hoàn toàn không có giấy tờ. Vì mọi thứ ở đây đều dựa trên hành vi không có giấy tờ, rất tiếc là tôi không thể đưa ra lời hứa rằng thông tin này sẽ vẫn chính xác sau một năm hoặc thậm chí một tháng kể từ bây giờ.
Ngoài ra, mọi thứ bên dưới giả định một chế độ xem cuộn dọc hoàn toàn có độ lệch y mà chúng tôi quan tâm; dịch sang hiệu số x , nếu cần, hy vọng là một bài tập dễ dàng cho người đọc.
Các trình xử lý sự kiện khác nhau khi ScrollViewthực hiện eventvà cho phép bạn có được vị trí cuộn hiện tại qua event.nativeEvent.contentOffset.y. Một số trình xử lý này có hành vi hơi khác nhau giữa Android và iOS, như chi tiết bên dưới.
Trên Android
Kích hoạt mọi khung hình khi người dùng đang cuộn, trên mọi khung hình trong khi chế độ xem cuộn đang lướt sau khi người dùng thả nó ra, trên khung hình cuối cùng khi chế độ xem cuộn dừng lại và cũng có thể bất cứ khi nào độ lệch của chế độ xem cuộn thay đổi do khung của nó thay đổi (ví dụ: do xoay từ ngang sang dọc).
Trên iOS
Kích hoạt khi người dùng đang kéo hoặc trong khi chế độ xem cuộn đang lướt, ở một số tần suất được xác định bởi scrollEventThrottlevà nhiều nhất một lần trên mỗi khung hình khi nào scrollEventThrottle={16}. Nếu người dùng nhả chế độ xem cuộn trong khi nó có đủ động lượng để lướt, onScrolltrình xử lý cũng sẽ kích hoạt khi nó nghỉ sau khi lướt. Tuy nhiên, nếu người dùng kéo và sau đó phát hành xem di chuyển trong khi nó đang đứng yên, onScrollđược không đảm bảo để lửa cho vị trí chính thức trừ khi scrollEventThrottleđã được thiết lập như vậy mà onScrollđám cháy mỗi khung di chuyển.
Có scrollEventThrottle={16}thể giảm chi phí hiệu suất để cài đặt bằng cách đặt nó thành một số lớn hơn. Tuy nhiên, điều này có nghĩa là điều đó onScrollsẽ không kích hoạt mọi khung hình.
Kích hoạt khi chế độ xem cuộn dừng lại sau khi lướt. Hoàn toàn không kích hoạt nếu người dùng thả chế độ xem cuộn trong khi nó đứng yên để nó không lướt đi.
onScrollEndDrag
Kích hoạt khi người dùng ngừng kéo chế độ xem cuộn - bất kể chế độ xem cuộn là đứng yên hay bắt đầu lướt.
Với những khác biệt này trong hành vi, cách tốt nhất để theo dõi sự bù đắp phụ thuộc vào hoàn cảnh cụ thể của bạn. Trong trường hợp phức tạp nhất (bạn cần hỗ trợ Android và iOS, bao gồm xử lý các thay đổi trong ScrollViewkhung của do xoay và bạn không muốn chấp nhận hình phạt hiệu suất trên Android từ cài đặt scrollEventThrottlethành 16) và bạn cần xử lý những thay đổi đối với nội dung trong chế độ xem cuộn, thì đó là một mớ hỗn độn chết tiệt.
Trường hợp đơn giản nhất là nếu bạn chỉ cần xử lý Android; chỉ cần sử dụng onScroll:
<ScrollView
onScroll={event => {
this.yOffset = event.nativeEvent.contentOffset.y
}}
>
Để hỗ trợ thêm cho iOS, nếu bạn hài lòng với việc kích hoạt onScrolltrình xử lý mọi khung hình và chấp nhận các tác động hiệu suất của điều đó và nếu bạn không cần xử lý các thay đổi về khung hình, thì nó chỉ phức tạp hơn một chút:
<ScrollView
onScroll={event => {
this.yOffset = event.nativeEvent.contentOffset.y
}}
scrollEventThrottle={16}
>
Để giảm chi phí hiệu suất trên iOS trong khi vẫn đảm bảo rằng chúng tôi ghi lại bất kỳ vị trí nào mà chế độ xem cuộn ổn định, chúng tôi có thể tăng scrollEventThrottlevà cung cấp thêm một onScrollEndDragtrình xử lý:
<ScrollView
onScroll={event => {
this.yOffset = event.nativeEvent.contentOffset.y
}}
onScrollEndDrag={event => {
this.yOffset = event.nativeEvent.contentOffset.y
}}
scrollEventThrottle={160}
>
Nhưng nếu chúng ta muốn xử lý các thay đổi về khung hình (ví dụ: vì chúng ta cho phép thiết bị được xoay, thay đổi chiều cao có sẵn cho khung của chế độ xem cuộn) và / hoặc thay đổi nội dung, thì chúng ta phải triển khai thêm cả hai onContentSizeChangevà onLayoutđể theo dõi chiều cao của cả hai khung của chế độ xem cuộn và nội dung của nó, và do đó liên tục tính toán độ chênh lệch tối đa có thể và suy ra khi độ lệch được tự động giảm do thay đổi kích thước khung hoặc nội dung:
<ScrollView
onLayout={event => {
this.frameHeight = event.nativeEvent.layout.height;
const maxOffset = this.contentHeight - this.frameHeight;
if (maxOffset < this.yOffset) {
this.yOffset = maxOffset;
}
}}
onContentSizeChange={(contentWidth, contentHeight) => {
this.contentHeight = contentHeight;
const maxOffset = this.contentHeight - this.frameHeight;
if (maxOffset < this.yOffset) {
this.yOffset = maxOffset;
}
}}
onScroll={event => {
this.yOffset = event.nativeEvent.contentOffset.y;
}}
onScrollEndDrag={event => {
this.yOffset = event.nativeEvent.contentOffset.y;
}}
scrollEventThrottle={160}
>
Vâng, nó khá kinh hoàng. Tôi cũng không chắc chắn 100% rằng nó sẽ luôn hoạt động bình thường trong trường hợp bạn đồng thời thay đổi kích thước của cả khung và nội dung của dạng xem cuộn. Nhưng đó là cách tốt nhất mà tôi có thể nghĩ ra và cho đến khi tính năng này được thêm vào trong chính khuôn khổ , tôi nghĩ đây là điều tốt nhất mà bất kỳ ai cũng có thể làm được.