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
Restoring scroll position not reliable #5
Comments
@anormal81 I can't reproduce your issue after I tried to write a sample like https://github.com/robert-luoqing/flutter_list_view/blob/master/example/lib/init_jump_after_loaddata.dart. Could you please check the code and help me to reproduce it? The two things you need to be aware of:
BTW:Does your list item's height can be changed after mount? Thanks. |
Thanks for your response. I'm very new to flutter, so maybe I made some huge mistakes and need more understanding in how everything works together. My data is a list of up to 200 items. When scrolling, the data changes, because the server returns a rolling window of max 200 items. After I got new data from the server, the code does the following:
FlutterListView has set an ObjectKey with the hashCode of the data. As far as I understand, that will rebuild the FlutterListView when the data have changed. In this setup, preferItemHeight and onItemHeight have an effect on how scrolling behaves. I'm not sure whether the height may change. I'm using flutter_html to display the formatted data. I will try to check your example. Maybe I will find a way to reproduce it or find what I'm doing wrong here ;-) |
@robert-bitguild I've just modified your example to simulate the behavior of the server API. I've attached the file. As you can see, the list starts by scrolling to the end of the 100 entries (index 99). When you press the button, a new list is generated with the old data. A new entry is inserted at index 0 of the list. The problem: But: |
@anormal81 After I checked your code. What you want to implement is called Keep Position Please check https://github.com/robert-luoqing/flutter_list_view#keep-position to know more about keep position |
@anormal81 BTW, Please remove Scrollbar around flutterListView. An issue exist in ScrollBar. See: flutter/flutter#97873 |
@anormal81 Please update flutter_list_view: ^1.1.5. The issue you post has been fixed. Of cause, you also can use "Keep position" functionality to resolve your issue. |
@robert-bitguild Thanks so much! It works great now in my app. I tried using keepPosition, but due to the rolling window, the whole list may change. Also some entries may get a different height when previous items are added. There seems to be another problem when scrolled to the top position. Could you please check again with my already provided code sample jump.txt
When setting the preferItemHeight to a larger value which will not be exceeded by the items, the scroll position seems fine. Would be great if you could fix that too. Many, many thanks |
@anormal81 The issue is not a bug, because you have set key to making FlutterListView become a different element. You can remove key or hardcode a key like below. child: FlutterListView( |
Yes, I've set the key to ensure that the whole list rebuilds when the data in background changes. As mentioned, I can not ensure, that existing elements will always stay the same height. The content of the items can have changed from e.g. single line to 2000 lines of content. Without the key with the hashCode, the scroll positions could not be updated properly. In my sample, I now removed the key completely and tried again. Scrolling item 97 or 96 to be partly visible at the bottom will also jump to another position after a button press (not with each press, had to try different positions. Seems to depend on the generated data in the list). preferItemHeight is set to 10. As I understand you, this should not happen without having a key set? So to understand it correctly: Initially the list will use the preferItemHeight or onItemHeight values to create the scroll positions? If I set them too low, there will be problems setting the correct initial scroll positions? Do you see any other possibility for my scenario? My app behaves like a messenger app, initially scrolled to the most recent message. The server provides a rolling window while scrolling or data changed by other clients. If the list of data does not contain the first and/or last message, a loading indicator is added as top and/or bottom item. Its size will be different as soon as the server has sent an updated list of data that will be visible. |
The widget is not what you said to follow preferItemHeight and onItemHeight. You can just remove it if the item height is not stable. The item height is not fixed after it is rendered. It is based on your list item. |
I've attached an updated sample. preferItemHeight ist set to 10 (which should have no impact as you said. 50 is the default and should not make any difference here). I removed the ObjectKey. Items are now larger (min. 10 lines) The both attached screenshot show the scroll position before and after the button was pressed. Expected: The scroll position must be restored to the correct offset. Can you please check what causes the wrong position here? There seems to be a case where a wrong offset is calculated. PS: With the ObjectKey active and preferItemHeight=200, the scroll positions are fine after button press (when scrolled to e.g. 96). With preferItemHeight=10, the positions sometimes is wrong. If the initial scroll position (based on initIndex and initOffset) is correctly calculated, the items should not have moved. |
@anormal81 I made a full chat example for you. Please check https://github.com/robert-luoqing/flutter_list_view/blob/master/example/lib/chat.dart If you don't want jump to last read after data loaded, just remove initIndex. You can manual invoke listViewController.sliverController.jumpToIndex(lastReadMessageIndex) when some button clicked; BTW: Need to update the package to flutter_list_view: ^1.1.6 |
Thanks so much for your example. I will analyze it and try to convert my code into something similar. The key difference seems to be the reverse order which prevents to always trying to scroll to the end. I hope there is also the difference why my list has some problems restoring the right positions. I will give feedback when I'm done. 😃 |
@robert-bitguild I've restructured a lot of my code, reversed the list of data, and so on. Now I have a working list with no strange scroll positions. KeepPosition works now. The big differences that I did not understand before were:
One suggestion: When the list of data is getting smaller (e.g. messages removed), I got an Now only one feature is not working as expected, maybe you have an idea: Is there anything that can be set using your list view to control this behavior? The used settings:
Thanks so much for the time your are investing. It helps a lot! |
@anormal81 I have added loadmore functionality into chat example. You can update it to review the code. The onItemKey issue has fixed, please update to flutter_list_view: ^1.1.7 BTW: If you don't need keepPosition, just set keepPosition: false, |
@robert-bitguild Thanks again. Version 1.1.7 does not fix the Range Error. Implementation in MessageListState:
Stack:
Getting back to my scenario: Setting keepPosition to off will create wrong scroll positions. The same in your chat sample when you disable keepPosition and use the "Mock To Receive" action from the AppBar. The added loadmore functionality in the chat sample only works to load more older messages. In my case, I have a rolling window, which means that the data list contains up to 200 messages, not more. When scrolling to a really old message, only 99 previous and 100 newer messages will be available in the list. There could be a lot more newer messages that are not available on client side. Scrolling and loading of messages will be available in both directions. In the current case, a loading indicator is available at the bottom of the list, as shown in my previous screenshot. When the user scrolls to the end of the current list, new data will be loaded. When new data is available, the list should stay at exactly the position of the valid messages, not the loading indicator. In result, the user will be able to scroll further to the bottom to see the newer messages.
Do you think that an enhancement would be possible to e.g. define per function which element is allowed to be used for keep position? Here are two screenshots to show the expected behavior (not the current behavior): User scrolled to the end of the list, but there are more messages available on server side New list of messages was sent to the client. The list keeps the positions of the visible items (identified by their key) |
After several different tries to get it working with keepPosition, I returned to my initial idea with setting an ObjectKey in order to create a new listView each time the data has changed. With this implementation I first need to save the first visible item including the offset and setting the new index and offset in the build call. Restoring the correct scroll position seems to work better when using a reverse list and In conclusion: I implemented my own keepPosition ;-) |
It is great. You can using initIndex to keep position. lol. https://github.com/robert-luoqing/flutter_list_view/blob/master/example/lib/chat.dart |
Thank you. I'll have a look the next days. The first example with initIndex seems to be similar to my implementation. Will let my co-workers test the current implementation. Hopefully they will not find another problem here and I can go on implementing further features ;-) |
I just updated to Version 1.1.11 Did not found another problem with scrolling in my current implementation. The Range Error is fixed too. Thank you! |
Hello all. Most of flutter_list_view works fine, but I have the following problem:
In my app, there is a list of chat messages that are rendered as HTML using flutter_html. Each message can have its own height, which I can't set myself.
When I try to initialize the list with initIndex and initOffset, sometimes the scroll position is just wrong. This depends on the preferItemHeight value. If I set a small value, the scroll position is fine when there are only single-line messages, but breaks for large messages. If a large value is set, the scroll position is fine when there are large values, but has problems when there are many one-line items.
It seems that the initial scroll position is restored with preferItemHeight or onItemHeight(...), just before the actual height of the item is known.
I tried to create a reproducible example, but was not able to create this behavior with test data.
Code I can currently share:
I hope you find an approach to find the problem
The text was updated successfully, but these errors were encountered: