Flutter - Getting the items information those are currently displaying in ScrollView
I. Overview
I believe everyone has anyone encountered some such needs
- After scrolling to a specified item, pop up a full-screen starter guide based on the size of the specified item
- During the scrolling process of the detail page, the module positioning navigation bar at the top needs to update the indicator index in time
- As the video list scrolls, item in the appropriate positions will automatically play the video
- …
In the daily development, there are still quite a lot of such similar functional requirements, so i encapsulate and publish a package: flutter_scrollview_observer
II. Scenarios
Let’s take a look at common application scenarios:
1. Get the first item information
You can get the current first child widget and all child widget information that is being displayed
2. The video list item plays automatically
When the item widget enters the middle area of the list, the video is played automatically
3. Module positioning
When scrolling to some specific module, the indicator at the top TabBar
switches to the corresponding module Tab
III. Useage
1. Basic useage
Create ListView
ListView _buildListView() {
return ListView.separated(
itemBuilder: (ctx, index) {
return _buildListItemView(index);
},
separatorBuilder: (ctx, index) {
return _buildSeparatorView();
},
itemCount: 50,
);
}
construct ListViewObserver
child
: Pass in theListView
instanceonObserve
: This callback listens for information about the item widgets those are currently being displayed
ListViewObserver(
child: _buildListView(),
onObserve: (resultMap) {
final model = resultMap[_sliverListViewContext];
if (model == null) return;
// Prints the first item index that is currently being displayed
print('firstChild.index -- ${model.firstChild.index}');
// Prints all item indexs those are currently being displayed
print('displaying -- ${model.displayingChildIndexList}');
},
)
In addition to the above common parameters, there are:
leadingOffset
: Top offset, used when the viewport of the list is fixed to be blocked by other viewsdynamicLeadingOffset
: Dynamic top offset, used when the viewport of the list is dynamically blocked by other views
Just look at the diagram here
// when NavigationBar is translucent
flutter: firstChild.index -- 0
flutter: displaying -- [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
flutter: firstChild.index -- 0
flutter: displaying -- [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
// when NavigationBar is completely opaque
flutter: firstChild.index -- 2
flutter: displaying -- [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
The scrolling process changes the transparency of the navigation bar at the top. At this premise:
- When translucent, we want all visible item widgets of the ListView to start from the very top
- When opaque is complete, we want all visible item widgets of the ListView to start at the bottom of the navigation bar
ListViewObserver(
...
dynamicLeadingOffset: () {
if (_navBgAlpha < 1) {
return 0;
}
return _safeAreaPaddingTop + _navContentHeight;
},
...
),
toNextOverPercent
: After the first item widget is fetched, if the ratio of the blocked size of the item widget to its own size exceeds this value, the next item widget will be as the first item widget.
2. Manual trigger observe
By default, the data is observed only while scrolling.
If an observation in a non-rolling state is required, you can use ListViewOnceObserveNotification
to trigger observe manually.
ListViewOnceObserveNotification().dispatch(_sliverListViewContext);
3. Item widget information
Observed model data:
class ListViewObserveModel {
/// The first observed model data
final ListViewObserveDisplayingChildModel firstChild;
/// Stores observing model list of displaying children widgets
final List<ListViewObserveDisplayingChildModel> displayingChildModelList;
/// Stores index list for children widgets those are displaying
List<int> get displayingChildIndexList =>
displayingChildModelList.map((e) => e.index).toList();
}
ListViewObserveDisplayingChildModel:
class ListViewObserveDisplayingChildModel {
/// The index of child widget
final int index;
/// The renderObject [RenderBox] of child widget
final RenderBox renderObject;
}
For more usage, please see GitHub: LinXunFeng/flutter_scrollview_observer
Series
- Flutter — Getting the items information those are currently displaying in ScrollView
- Flutter — Scrolling to a specific item in the ScrollView!🔥
- Flutter — Quickly implement the effect of the chat session list, perfect 💯
- Flutter — New upgrade😱Supports observing ScrollView built by third package💪
- Flutter — Play alternately waterfall flow video 🎞
- Flutter — Keep IM message position greatly upgraded (supports generative messages like ChatGPT) 🤖
- Flutter — Anti-occlusion of form in ScrollView 🗒
- Flutter — Quickly achieve half-view exposure statistic 📊
- Flutter — How to quickly implement an contact list page (azlist) 📓
- Flutter — Supports observing NestedScrollView, with greater compatibility 😈