-
Notifications
You must be signed in to change notification settings - Fork 297
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DF] feat(#547): add experimentalScrollPositionManagement
support to FlashList
#824
base: main
Are you sure you want to change the base?
Conversation
1d653b3
to
556822a
Compare
experimentalScrollPositionManagement
support to FlashList
556822a
to
15e1f4c
Compare
keep it up! we need this merged asap! 🔥 🚀 |
would some be kind enough to approve this? |
@naqvitalha would you please approve this? |
How can I install flash-list from this branch |
does this require react native version greater than some number? I tried this on our 0.62.3 project and got
// ...
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const ScrollViewRNRaw: Component<ScrollViewProps> = ScrollViewRN.render().type;
// ... |
Super excited about this! I've been testing out this change for a while now, and it's been mostly awesome. But when I tried to scroll while adding a new item, I noticed some jitters. I made a quick video to show what's going on. In the video, you'll notice I'm also firing off a new message every second. telegram-cloud-document-2-5424748569082999196.mp4 |
Tested this PR on iOS and it seems like it does not work, at least in my case. I'm implementing similar to Instagram navigation where user needs to navigate from a grid to a particular item in a list. const { data } = useListData()
const [dataToDisplay, setDataToDisplay] = useState(() => {
return data.slice(route.params.activeItemIndex, data.length)
})
useEffect(() => {
requestAnimationFrame(() => {
setDataToDisplay(data)
})
}, []) I use PS. Great job so far, exciting for this feature to be part of flash-list. Let me know if you need more info on this. |
this PR has been open for 6 weeks now. is anyone going to review it? |
Folks, apologies for the delay on this feature. I'm gonna review this tomorrow! This might have some bugs but we'll continue to address and make it perfect overtime. |
/** Checks for overlaps or gaps between adjacent items and then applies a correction (Only Grid layouts with varying spans) | ||
* Performance: RecyclerListView renders very small number of views and this is not going to trigger multiple layouts on Android side. Not expecting any major perf issue. */ | ||
fun clearGapsAndOverlaps(sortedItems: Array<CellContainer>) { | ||
fun clearGapsAndOverlaps(sortedItems: Array<CellContainer>, scrollView: ScrollView, maintainTopContentPosition: Boolean) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the flag can be maintained as a variable within this class and final diff can be applied by AutoLayout. That will keep this class independent of view layer like it used to be,
@@ -15,13 +17,21 @@ class AutoLayoutShadow { | |||
private var lastMaxBound = 0 // Tracks where the last pixel is drawn in the visible window | |||
private var lastMinBound = 0 // Tracks where first pixel is drawn in the visible window | |||
|
|||
private var isInitialRender = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do we need the initial render for? A comment would be helpful
src/BiDirectionalScrollView.tsx
Outdated
View, | ||
} from "react-native"; | ||
|
||
import { BidirectionalFlatlist } from "./BidirectionalFlatlist"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we call it something else? I got confused if we're using FlatList :D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does BidirectionalList
sound?
this.props.experimentalScrollPositionManagement && | ||
this.props.renderScrollComponent | ||
) { | ||
throw new CustomError(ExceptionList.customMaintainScrollNotSupported); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if people can still use custom scroll component by using DoubleSidedScrollView instead of ScrollView in their component? In that case we can export DoubleSidedScrollView from FlashList too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That could be possible. I think it makes sense to restrict users from doing this for now though. This feature is experimental at the moment and its probably easier to maintain if we restrict consumers of the library to using our implementation of the DoubleSidedScrollView
for now.
If this implementation proves to be stable, then I think we can allow users to customize as they feel appropriate. What are your thoughts?
src/FlashList.tsx
Outdated
@@ -382,7 +398,10 @@ class FlashList<T> extends React.PureComponent< | |||
itemAnimator={this.itemAnimator} | |||
suppressBoundedSizeException | |||
externalScrollView={ | |||
renderScrollComponent as RecyclerListViewProps["externalScrollView"] | |||
this.props.experimentalScrollPositionManagement && | |||
Platform.OS === "android" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the filers in config folder to add platform check. We discourage inline platform checks.
@@ -500,6 +522,10 @@ class FlashList<T> extends React.PureComponent< | |||
...getCellContainerPlatformStyles(this.props.inverted!!, parentProps), | |||
}} | |||
index={parentProps.index} | |||
stableId={ | |||
/* Empty string is used so the list can still render without an extractor */ | |||
this.props.keyExtractor?.(parentProps.data, parentProps.index) ?? "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we skip this if the flag is off?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so, in Objective-C its always expecting a stable id to have some value.
cc @friyiajr - seems like fairly minor comments. this is a huge feature to get shipped to the community. |
can we please ship this feature asap? @naqvitalha @friyiajr |
any success on that? |
You can try |
unable to build after this. any work arounds? |
You need to replace @shopify/flash-list to @huunguyen312/flash-list |
okay, I got it running. But did the experimentalScrollPositionManagement worked on android? |
@naqvitalha @friyiajr any updates on this PR? |
Any updates on this +1 ? |
while this stuck for approval, you can do is append one element at top and then use scrollToIndex and put index = 1. it will maintain its position. |
…s horizontally
… added to TypeScript
ddd4aaa
to
b677969
Compare
b677969
to
788eb40
Compare
hope someone to review this and get it merged. |
Hi there! I found the app crashing due to incorrectness in Btw. Those crashes occur even if the Maybe I'm doing something wrong? Below, is the brief of the error. Thanks! EDIT: idk why, it started working. 😱
|
@irion94 +1, also got that error testing this PR on Android in app with horizontal flashlists. |
I clone the repo The error is "TypeError (0 , PlatformHelper_1.getBidirectionalScrollView) is not a function" This error is located at: I fix it by export "getBidirectionalScrollView" function from both |
I'm willing to sponsor someone at Shopify to review and merge this. cc @naqvitalha feel free to DM me to set this up. |
happy holidays everyone! any update on this PR? i wish i could contribute instead of just coming in here and poking, but i literally don't have any more time in my days. 😭 |
Exciting stuff! Also willing to sponsor someone to get this landed if it helps. |
This is so crucial to this library! Would love to see it implemented. |
Hi! Is there something new after one year? Thank you. |
please someone review and merge 🙏 |
This is a limitation of the approach taken in this patch. Since recyclerlistview, which is used by flash-list, is responsible for layouting the list items, and recyclerlistview does not really support maintaining a "visible position" in its layouting algorithm, these issues cannot be solved without reimplementing the layout algorithm in recyclerlistview. I have done so, and it seems to solve most issues that I have with flash-list, including choppy scrolling on bad size estimates, inaccurate scrollToIndex, and maintaining positions of visible items across data changes. I'll package it up in a bit after I clean the repo a bit more, and would be happy if you guys would want to test it. |
As I've alluded to, to maintain visible content position properly is related to choppy scrolling on bad size estimates and also inaccurate programmatic scrolling, and requires deeper changes to fix. I've published an analysis of this problem and a patch here; feel free to test it out. Note that instead of attempting to replicate ScrollView's |
any updates on this PR? |
@wqhui Try out https://github.com/LegendApp/legend-list, it has automatic scroll to the top and quite powerful maintainVisibleContentPosition implementation. |
Description
Fixes: #547
Adds support for maintaining vertical content position in iOS and Android. Also fixes resizing issues when changing device orientation from portrait to landscape
Reviewers’ hat-rack 🎩
Messages Test:
Messages.tsx
Messages.tsx.txt
Twitter Test:
experimentalScrollPositionManagement
property to the FlashList inTwitter.tsx
Screenshots or videos (if needed)
iOS Demo
Messages:
Simulator.Screen.Recording.-.iPhone.14.Pro.-.2023-04-24.at.18.36.26.mp4
Twitter:
Screen.Recording.2023-04-24.at.6.38.56.PM.mov
Android Demo
Messages:
a_messages.mov
Twitter:
a_twitter.mov
Checklist