Created
December 28, 2021 01:53
-
-
Save diegoveloper/65bc470f062c31bb5186e9f9a8367d05 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class DiegoveloperDataTable extends StatefulWidget { | |
const DiegoveloperDataTable({Key? key}) : super(key: key); | |
@override | |
State<DiegoveloperDataTable> createState() => _DiegoveloperDataTableState(); | |
} | |
const itemWidth = 120.0; | |
final itemsHeader = List.generate( | |
10, (index) => SizedBox(width: itemWidth, child: Text('Header $index'))); | |
class _DiegoveloperDataTableState extends State<DiegoveloperDataTable> { | |
final _controllerHorizontalHeader = CustomScrollController(); | |
final _controllerHorizontalBody = CustomScrollController(); | |
void _listenScrollHeader() { | |
_controllerHorizontalBody.jumpToWithoutGoingIdleAndKeepingBallistic( | |
_controllerHorizontalHeader.offset); | |
} | |
void _listenScrollBody() { | |
_controllerHorizontalHeader.jumpToWithoutGoingIdleAndKeepingBallistic( | |
_controllerHorizontalBody.offset); | |
} | |
@override | |
void initState() { | |
_controllerHorizontalHeader.addListener(_listenScrollHeader); | |
_controllerHorizontalBody.addListener(_listenScrollBody); | |
super.initState(); | |
} | |
@override | |
void dispose() { | |
_controllerHorizontalHeader.removeListener(_listenScrollHeader); | |
_controllerHorizontalBody.removeListener(_listenScrollBody); | |
_controllerHorizontalHeader.dispose(); | |
_controllerHorizontalBody.dispose(); | |
super.dispose(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
body: CustomScrollView( | |
slivers: [ | |
const SliverToBoxAdapter( | |
child: Card( | |
child: Center( | |
child: FlutterLogo( | |
size: 300, | |
), | |
), | |
), | |
), | |
SliverAppBar( | |
title: SingleChildScrollView( | |
controller: _controllerHorizontalHeader, | |
scrollDirection: Axis.horizontal, | |
child: Row( | |
children: itemsHeader, | |
), | |
), | |
pinned: true, | |
), | |
SliverToBoxAdapter( | |
child: SingleChildScrollView( | |
controller: _controllerHorizontalBody, | |
scrollDirection: Axis.horizontal, | |
child: Column( | |
children: List.generate( | |
20, | |
(index) => Row( | |
children: List.generate( | |
itemsHeader.length, | |
(index) => SizedBox( | |
width: itemWidth, | |
child: ListTile( | |
title: Text('Item :$index'), | |
), | |
), | |
), | |
), | |
), | |
), | |
), | |
) | |
], | |
), | |
); | |
} | |
} | |
class CustomScrollController extends ScrollController { | |
CustomScrollController({ | |
double initialScrollOffset = 0.0, | |
bool keepScrollOffset = true, | |
String? debugLabel, | |
}) : super( | |
initialScrollOffset: initialScrollOffset, | |
keepScrollOffset: keepScrollOffset, | |
debugLabel: debugLabel); | |
@override | |
_SilentScrollPosition createScrollPosition( | |
ScrollPhysics physics, | |
ScrollContext context, | |
ScrollPosition? oldPosition, | |
) { | |
return _SilentScrollPosition( | |
physics: physics, | |
context: context, | |
oldPosition: oldPosition, | |
initialPixels: initialScrollOffset, | |
); | |
} | |
void jumpToWithoutGoingIdleAndKeepingBallistic(double value) { | |
assert(positions.isNotEmpty, 'ScrollController not attached.'); | |
for (_SilentScrollPosition position in List<ScrollPosition>.from(positions) | |
.whereType<_SilentScrollPosition>()) { | |
position.jumpToWithoutGoingIdleAndKeepingBallistic(value); | |
} | |
} | |
} | |
class _SilentScrollPosition extends ScrollPositionWithSingleContext { | |
_SilentScrollPosition({ | |
required ScrollPhysics physics, | |
required ScrollContext context, | |
ScrollPosition? oldPosition, | |
double? initialPixels, | |
}) : super( | |
physics: physics, | |
context: context, | |
oldPosition: oldPosition, | |
initialPixels: initialPixels, | |
); | |
void jumpToWithoutGoingIdleAndKeepingBallistic(double value) { | |
if (pixels != value) { | |
forcePixels(value); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment