Skip to content

Commit

Permalink
Merge pull request #3 from SimonWang9610/box-observer
Browse files Browse the repository at this point in the history
Box observer
  • Loading branch information
SimonWang9610 committed Mar 15, 2023
2 parents 42f6449 + 21b257c commit ffcaf89
Show file tree
Hide file tree
Showing 27 changed files with 1,458 additions and 1,554 deletions.
259 changes: 110 additions & 149 deletions README.md

Large diffs are not rendered by default.

106 changes: 54 additions & 52 deletions example/lib/example/custom_view_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,19 @@ class CustomViewExample extends StatefulWidget {
class _CustomViewExampleState extends State<CustomViewExample> {
int _itemCount = 30;

final PositionedScrollController _controller =
PositionedScrollController.multiObserver();
final ScrollController _controller = ScrollController();

final keepAliveObserverKey = "keepAlive";
final gridObserverKey = "grid";
final listObserverKey = "list";
final appbarObserverKey = "appbar";
late final keepAlive = ScrollObserver.sliverMulti(itemCount: _itemCount);
late final grid = ScrollObserver.sliverMulti(itemCount: _itemCount);
late final list = ScrollObserver.sliverMulti(itemCount: _itemCount);
late final appbar = ScrollObserver.sliverSingle();

@override
void dispose() {
keepAlive.clear();
grid.clear();
list.clear();
appbar.clear();
_controller.dispose();
super.dispose();
}
Expand All @@ -37,35 +40,43 @@ class _CustomViewExampleState extends State<CustomViewExample> {
body: Column(
children: [
SliverJumpWidget(
label: keepAliveObserverKey,
onJump: (index) => _controller.jumpToIndex(
index,
whichObserver: keepAliveObserverKey,
),
label: "KeepAlive Jump",
onJump: (index) {
keepAlive.jumpToIndex(
index,
position: _controller.position,
);
},
),
SliverJumpWidget(
label: gridObserverKey,
onJump: (index) => _controller.jumpToIndex(
index,
whichObserver: gridObserverKey,
),
label: "AppBar Animate",
force: true,
onJump: (index) {
appbar.animateToIndex(
index,
position: _controller.position,
duration: const Duration(milliseconds: 200),
curve: Curves.bounceIn,
);
},
),
SliverJumpWidget(
label: listObserverKey,
onJump: (index) => _controller.jumpToIndex(
index,
whichObserver: listObserverKey,
),
label: "Grid Jump",
onJump: (index) {
grid.jumpToIndex(
index,
position: _controller.position,
);
},
),
SliverJumpWidget(
label: appbarObserverKey,
force: true,
onJump: (index) => _controller.animateToIndex(
index,
whichObserver: appbarObserverKey,
duration: const Duration(milliseconds: 120),
curve: Curves.bounceInOut,
),
label: "List Jump",
onJump: (index) {
list.jumpToIndex(
index,
position: _controller.position,
);
},
),
Expanded(
child: CustomScrollView(
Expand All @@ -76,27 +87,21 @@ class _CustomViewExampleState extends State<CustomViewExample> {
delegate: PositionedChildBuilderDelegate(
childCount: _itemCount,
(context, index) => IndexedKeepAliveItem(
label: keepAliveObserverKey,
label: "KeepAlive",
index: index,
),
addRepaintBoundaries: false,
addSemanticIndexes: true,
addAutomaticKeepAlives: true,
observer: _controller.createOrObtainObserver(
itemCount: _itemCount,
observerKey: keepAliveObserverKey,
),
observer: keepAlive,
),
),
SliverAppBar.medium(
pinned: true,
floating: true,
automaticallyImplyLeading: false,
title: ObserverProxy(
observer: _controller.createOrObtainObserver(
hasMultiChild: false,
observerKey: appbarObserverKey,
),
title: SliverObserverProxy(
observer: appbar,
child: const Text("Pinned App bar"),
),
),
Expand All @@ -118,10 +123,7 @@ class _CustomViewExampleState extends State<CustomViewExample> {
addRepaintBoundaries: false,
addSemanticIndexes: true,
addAutomaticKeepAlives: true,
observer: _controller.createOrObtainObserver(
itemCount: _itemCount,
observerKey: gridObserverKey,
),
observer: grid,
),
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
Expand All @@ -133,19 +135,15 @@ class _CustomViewExampleState extends State<CustomViewExample> {
delegate: PositionedChildBuilderDelegate(
childCount: _itemCount,
(context, index) => ListTile(
key: ValueKey<int>(index),
leading: CircleAvatar(
child: Text(listObserverKey),
leading: const CircleAvatar(
child: Text("List"),
),
title: Text("$listObserverKey $index"),
title: Text("list $index"),
),
addRepaintBoundaries: false,
addSemanticIndexes: true,
addAutomaticKeepAlives: true,
observer: _controller.createOrObtainObserver(
itemCount: _itemCount,
observerKey: listObserverKey,
),
observer: list,
),
),
],
Expand All @@ -155,7 +153,11 @@ class _CustomViewExampleState extends State<CustomViewExample> {
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_controller.debugCheckOnstageItems();
final scrollExtent = ScrollExtent.fromPosition(_controller.position);
keepAlive.debugCheckOnstageItems(scrollExtent: scrollExtent);
appbar.debugCheckOnstageItems(scrollExtent: scrollExtent);
grid.debugCheckOnstageItems(scrollExtent: scrollExtent);
list.debugCheckOnstageItems(scrollExtent: scrollExtent);
},
child: const Icon(Icons.visibility_off_rounded),
),
Expand Down
2 changes: 2 additions & 0 deletions example/lib/example/examples.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ export './custom_view_example.dart';
export './grid_example.dart';
export './official_list_example.dart';
export './reorderable_list_example.dart';
export './single_child_scroll_view_example.dart';
export './list_wheel_example.dart';
21 changes: 11 additions & 10 deletions example/lib/example/grid_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ class PositionedGridExample extends StatefulWidget {
class _PositionedGridExampleState extends State<PositionedGridExample> {
int _itemCount = 30;

final PositionedScrollController _controller =
PositionedScrollController.singleObserver();
final ScrollController _controller = ScrollController();
late final grid = ScrollObserver.sliverMulti(itemCount: _itemCount);

final String observerKey = "grid";
@override
Expand Down Expand Up @@ -53,15 +53,16 @@ class _PositionedGridExampleState extends State<PositionedGridExample> {
),
SliverJumpWidget(
label: "without animation",
onJump: (index) => _controller.jumpToIndex(
index,
),
onJump: (index) {
grid.jumpToIndex(index, position: _controller.position);
},
),
SliverJumpWidget(
label: "animation",
onJump: (index) {
_controller.animateToIndex(
grid.animateToIndex(
index,
position: _controller.position,
duration: const Duration(milliseconds: 200),
curve: Curves.bounceInOut,
);
Expand All @@ -79,8 +80,7 @@ class _PositionedGridExampleState extends State<PositionedGridExample> {
title: Text("Positioned Grid Example $index"),
),
childCount: _itemCount,
observer:
_controller.createOrObtainObserver(itemCount: _itemCount),
observer: grid,
),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
Expand All @@ -91,15 +91,16 @@ class _PositionedGridExampleState extends State<PositionedGridExample> {
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_controller.debugCheckOnstageItems();
final scrollExtent = ScrollExtent.fromPosition(_controller.position);
grid.debugCheckOnstageItems(scrollExtent: scrollExtent);
},
child: const Icon(Icons.visibility_off_rounded),
),
);
}

void _goStart() {
_controller.showInViewport();
grid.showInViewport(_controller.position);
}

void _addItem() {
Expand Down
82 changes: 82 additions & 0 deletions example/lib/example/list_wheel_example.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import 'package:flutter/material.dart';
import 'package:positioned_scroll_observer/positioned_scroll_observer.dart';
import 'sliver_jump.dart';

class ListWheelExample extends StatefulWidget {
const ListWheelExample({super.key});

@override
State<ListWheelExample> createState() => _ListWheelExampleState();
}

class _ListWheelExampleState extends State<ListWheelExample> {
final ScrollController _controller = ScrollController();

final _observer = ScrollObserver.boxMulti(
axis: Axis.vertical,
itemCount: 30,
);

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text("Single Child Scroll View example"),
),
body: Column(
children: [
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: 200),
curve: Curves.easeInSine,
);
},
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 40),
child: ListWheelScrollView(
controller: _controller,
itemExtent: 100,
children: [
for (int i = 0; i < 30; i++)
ObserverProxy(
observer: _observer,
child: DecoratedBox(
decoration: BoxDecoration(border: Border.all()),
child: Center(
child: Text("List Wheel $i"),
),
),
)
],
),
),
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_observer.debugCheckOnstageItems(
scrollExtent: ScrollExtent.fromPosition(_controller.position),
);
},
child: const Icon(Icons.visibility),
),
);
}
}
30 changes: 23 additions & 7 deletions example/lib/example/official_list_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ class OfficialListExample extends StatefulWidget {
}

class _OfficialListExampleState extends State<OfficialListExample> {
int _itemCount = 30;
int _itemCount = 1000;

final ScrollController _controller = ScrollController();
late final ScrollObserver _observer =
ScrollObserver.multiChild(itemCount: _itemCount);

late final SliverScrollObserver _observer =
MultiChildSliverObserver(itemCount: _itemCount);

@override
void dispose() {
Expand All @@ -27,6 +28,20 @@ class _OfficialListExampleState extends State<OfficialListExample> {

@override
Widget build(BuildContext context) {
ListView.builder(
controller: _controller,
itemBuilder: (context, index) => SliverObserverProxy(
observer: _observer,
child: ListTile(
key: ValueKey<int>(index),
leading: const CircleAvatar(
child: Text("L"),
),
title: Text("Positioned List Example $index"),
),
),
itemCount: _itemCount,
);
return Scaffold(
appBar: AppBar(
centerTitle: true,
Expand Down Expand Up @@ -66,15 +81,15 @@ class _OfficialListExampleState extends State<OfficialListExample> {
_observer.animateToIndex(
index,
position: _controller.position,
duration: const Duration(milliseconds: 200),
duration: const Duration(milliseconds: 1000),
curve: Curves.fastLinearToSlowEaseIn,
);
},
),
Expanded(
child: ListView.builder(
controller: _controller,
itemBuilder: (context, index) => ObserverProxy(
itemBuilder: (context, index) => SliverObserverProxy(
observer: _observer,
child: ListTile(
key: ValueKey<int>(index),
Expand Down Expand Up @@ -128,10 +143,11 @@ class OfficialSeparatedListExample extends StatefulWidget {

class _OfficialSeparatedListExampleState
extends State<OfficialSeparatedListExample> {
int _itemCount = 30;
int _itemCount = 1000;

final ScrollController _controller = ScrollController();
late final ScrollObserver _observer = ScrollObserver.multiChild(

late final _observer = ScrollObserver.sliverMulti(
itemCount: _computeActualChildCount(_itemCount),
)
..targetToRenderIndex = _toRenderIndex
Expand Down
Loading

0 comments on commit ffcaf89

Please sign in to comment.