class OfficialListExample extends StatefulWidget {
const OfficialListExample({super.key});
@override
State<OfficialListExample> createState() => _OfficialListExampleState();
}
class _OfficialListExampleState extends State<OfficialListExample> {
int _itemCount = 100;
final ScrollController _controller = ScrollController();
late final SliverScrollObserver _observer =
MultiChildSliverObserver(itemCount: _itemCount);
@override
void initState() {
// TODO: implement initState
super.initState();
}
late final List<Widget> _items = List.generate(_itemCount, (index) => index)
.map(
(index) => ObserverProxy(
observer: _observer,
child: ListTile(
leading: const CircleAvatar(
child: Text("L"),
),
title: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Positioned List Example $index"),
SizedBox(
height: index.toDouble(),
)
],
),
),
),
)
.toList();
@override
void dispose() {
_controller.dispose();
_observer.clear();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text("List View Example"),
),
body: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
OutlinedButton(
onPressed: () {
_observer.showInViewport(
_controller.position,
alignment: 0.0,
);
},
child: const Text("Go to start"),
),
OutlinedButton(
onPressed: () {
_observer.showInViewport(
_controller.position,
alignment: 0.5,
);
},
child: const Text("Go to middle"),
),
OutlinedButton(
onPressed: () {
_observer.showInViewport(
_controller.position,
alignment: 1.0,
);
},
child: const Text("Go to end"),
),
],
),
SliverJumpWidget(
label: "without animation",
onJump: (index) {
_observer.jumpToIndex(
index,
position: _controller.position,
);
},
),
SliverJumpWidget(
label: "animation",
onJump: (index) {
_observer.animateToIndex(
index,
position: _controller.position,
duration: const Duration(milliseconds: 1000),
curve: Curves.fastLinearToSlowEaseIn,
);
},
),
Expanded(
child: ListView.builder(
controller: _controller,
reverse: true,
physics: const PositionRetainedScrollPhysics(),
itemBuilder: (context, index) => _items[index],
itemCount: _itemCount,
),
)
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_addItem();
// _observer.getVisibleItems(
// scrollExtent: ScrollExtent.fromPosition(_controller.position),
// );
// print(_observer.visibleRatioInViewport(
// ScrollExtent.fromPosition(_controller.position)));
},
child: const Icon(Icons.visibility_off_rounded),
),
);
}
void _goStart() {
_observer.showInViewport(_controller.position);
}
void _addItem() {
_itemCount++;
_observer.itemCount = _itemCount;
_items.insert(
0,
ObserverProxy(
observer: _observer,
child: ListTile(
leading: const CircleAvatar(
child: Text("L"),
),
title: Column(
children: [
Text("Positioned List Example $_itemCount"),
SizedBox(
height: _itemCount.toDouble(),
)
],
),
),
),
);
setState(() {});
}
void _deleteItem() {
_itemCount = max(--_itemCount, 0);
_observer.itemCount = _itemCount;
_items.removeLast();
setState(() {});
}
}