Closed shahbazhashmi closed 4 months ago
I can't reproduce your issue I have made a sample with your code snippet. But it works fine. The code is here. https://github.com/robert-luoqing/flutter_list_view/blob/master/example/lib/init_jump2.dart
Could you please rewrite the code, reproduce the issue, and return it to me? I can fix it if it is a bug.
Here is the code. To avoid boilerplate I used hooks
class TestApiWidget extends HookWidget {
TestApiWidget({super.key});
@override
Widget build(final BuildContext context) {
final chatListScrollController = useMemoized(FlutterListViewController.new);
final dataList = useState(List.generate(50, (final index) => index + 1));
void scrollToEdgeListener() {
if (chatListScrollController.position.atEdge) {
final isTop = chatListScrollController.position.pixels == 0;
if (isTop) {
/// At the top
} else {
/// At the bottom
dataList.value = List.generate(dataList.value.length + 50, (final index) => index + 1);
}
}
}
useEffect(
() {
if (dataList.value.isNotEmpty) {
chatListScrollController.addListener(scrollToEdgeListener);
}
return () {
chatListScrollController.removeListener(scrollToEdgeListener);
};
},
[dataList.value.isNotEmpty],
);
return FlutterListView(
controller: chatListScrollController,
shrinkWrap: true,
delegate: FlutterListViewDelegate(
(final BuildContext _, final int index) {
final item = dataList.value[index];
return Container(
margin: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
child: Text(item.toString()),
);
},
onItemKey: (final index) => dataList.value[index].toString(),
childCount: dataList.value.length,
initIndex: 10,
disableCacheItems: true,
),
);
}
}
Here I reinitialise dataList (which rebuilds widget) and add 50 more items on scroll to bottom. initIndex works only once not on further rebuilds. It should support dynamic initIndex.
It works fine when I test. Please reference the screen record. It jump to 10 in the first loads. I think there is some gap between us. For initIndex property, The defined as below
initIndex: It only works once when FlutterListView loads data for the first time. If you want to jump to the index after the data change. you can invoke chatListScrollController.sliverController.jumpToIndex(50); after data changed
What behavior you want in the list? you want to reverse and keep position when load data?
More chat example, please ref https://github.com/robert-luoqing/flutter_list_view/blob/master/example/lib/chat.dart https://github.com/robert-luoqing/flutter_list_view/blob/master/example/lib/chat2.dart
Reference code https://github.com/robert-luoqing/flutter_list_view/blob/master/example/lib/init_jump2.dart
void scrollToEdgeListener() {
if (chatListScrollController.position.atEdge) {
final isTop = chatListScrollController.position.pixels == 0;
if (isTop) {
/// At the top
} else {
/// At the bottom
dataList.value = List.generate(
dataList.value.length + 50, (final index) => index + 1);
// Jump to 50.
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
chatListScrollController.sliverController.jumpToIndex(50);
});
}
}
}
I send list of chats and initial index from a cubit. I create this initial index based on data. If it has older data I send this initial index : old data length - 1. I fetch old data when user scroll to top.
So the logic is simple, when we get new data initial index should be n-1. When we get old data it should be index of first chat in previous list - 1.
The logic to calculate initial index works fine. But I am not able to use it correctly in the widget.
About your logic in chat, I think you need refer https://github.com/robert-luoqing/flutter_list_view/blob/master/example/lib/chat.dart
It is specify for chat, The logic is:
FlutterListView(
reverse: true,
controller: listViewController,
delegate: FlutterListViewDelegate(
(BuildContext context, int index) => _renderItem(index),
childCount: messages.length,
onItemKey: (index) => messages[index].id.toString(),
keepPosition: true,
keepPositionOffset: 40,
initIndex: initIndex,
initOffset: initOffset,
initOffsetBasedOnBottom: initOffsetBasedOnBottom,
forceToExecuteInitIndex: forceToExecuteInitIndex,
firstItemAlign: FirstItemAlign.end))),
The user case for initIndex is that you want jump to latest unread message when load your messages. It is not to use initIndex to keep scroll to last message.
I have made a simple chat. please ref https://github.com/robert-luoqing/flutter_list_view/blob/master/example/lib/simple_chat.dart
The code have below logic:
Notice: keepPosition: true, It will cause that No any scroll down when new message coming and scroll offset is above 40. The case is when user read old message, He/She don't want be disturb when new message coming.
If you want more advance feature. You can read chat.dart and chat2.dart.
Hope useful for you.
I am trying to put dynamic initIndex in the list view but it just picks random index. Although it works perfectly with 0 and n -1 index. This my code