Created
February 26, 2024 13:59
-
-
Save epatel/d9236484817e3995e933954387822d3a to your computer and use it in GitHub Desktop.
This file contains 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
import 'dart:math'; | |
import 'package:flutter/material.dart'; | |
void main() => runApp(const AnimatedContainerExampleApp()); | |
class AnimatedContainerExampleApp extends StatelessWidget { | |
const AnimatedContainerExampleApp({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
home: OrderToolScrollTest(), | |
); | |
} | |
} | |
class OrderToolScrollTest extends StatefulWidget { | |
const OrderToolScrollTest({super.key}); | |
@override | |
State<OrderToolScrollTest> createState() => _OrderToolScrollTestState(); | |
} | |
class _OrderToolScrollTestState extends State<OrderToolScrollTest> { | |
int sections = 6; | |
ScrollController controller = ScrollController(); | |
final double offsetTop = 134 /**ORDER_TOOL_TOP_PADDING */; | |
final double sectionSpacing = 24; //Insets.insets5; | |
final double buttonHeight = 56; | |
final double buttonWidth = | |
330 /**ORDER_TOOL_SIDE_MENU_WIDTH */ - (24 /**Insets.insets5 */ * 3); | |
int sectionsPassed = 0; | |
List<GlobalKey> keys = []; | |
List<Color> colors = []; | |
List<bool> completed = []; | |
double scrollIndicatorAlignment = -1; | |
double scrollViewHeight = 0; | |
@override | |
void initState() { | |
for (var i = 0; i < sections; i++) { | |
keys.add(GlobalKey()); | |
colors.add( | |
Color((Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(1), | |
); | |
completed.add(false); | |
} | |
controller.addListener(() { | |
setState( | |
() => scrollIndicatorAlignment = | |
((controller.offset / controller.position.maxScrollExtent) * 2) - 1, | |
); | |
// debugPrint(controller.offset.toString()); | |
// debugPrint('max:${controller.position.maxScrollExtent}'); | |
// debugPrint('alignment:${scrollIndicatorAlignment}'); | |
sectionsPassed = 0; | |
for (int i = 0; i < keys.length; i++) { | |
var box = keys[i].currentContext!.findRenderObject()! as RenderBox; | |
var yPosition = box.localToGlobal(Offset.zero).dy; | |
// debugPrint('Height of key section $i: ${yPosition}'); | |
if (yPosition < 100 && i != 0) { | |
sectionsPassed++; | |
} | |
} | |
// debugPrint('Sections passed ${sectionsPassed}'); | |
}); | |
WidgetsBinding.instance.addPostFrameCallback((timeStamp) { | |
// debugPrint('$scrollViewHeight'); | |
}); | |
super.initState(); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
body: Stack( | |
children: [ | |
SizedBox( | |
width: double.infinity, | |
height: MediaQuery.of(context).size.height, | |
child: SingleChildScrollView( | |
controller: controller, | |
child: Center( | |
child: SizedBox( | |
width: 1440 /**LARGE_SCREEN_MAX_WIDTH */, | |
child: Padding( | |
padding: EdgeInsets.only( | |
top: offsetTop - sectionSpacing, | |
left: 330 /**ORDER_TOOL_SIDE_MENU_WIDTH */ + | |
32 /**Insets.insets6 */ * 2, | |
), | |
child: Column( | |
crossAxisAlignment: CrossAxisAlignment.start, | |
children: [ | |
for (var i = 0; i < sections; i++) _section(index: i), | |
const SizedBox(height: 900), | |
], | |
), | |
), | |
), | |
), | |
), | |
), | |
Center( | |
child: Container( | |
width: 1440 /**LARGE_SCREEN_MAX_WIDTH */, | |
padding: EdgeInsets.only( | |
left: 32, | |
/**Insets.insets6 */ | |
top: offsetTop, | |
), | |
child: Align( | |
alignment: Alignment.topLeft, | |
child: SizedBox( | |
width: 330 /**ORDER_TOOL_SIDE_MENU_WIDTH */, | |
child: Container( | |
padding: const EdgeInsets.all(24), | |
child: Column( | |
mainAxisSize: MainAxisSize.min, | |
crossAxisAlignment: CrossAxisAlignment.start, | |
children: [ | |
const Text('Rubrik'), | |
Row( | |
crossAxisAlignment: CrossAxisAlignment.start, | |
children: [ | |
Flexible( | |
child: Column( | |
children: [ | |
for (var i = 0; i < sections; i++) | |
GestureDetector( | |
onTap: () { | |
Scrollable.ensureVisible( | |
keys[i].currentContext!, | |
duration: Durations.medium1, | |
); | |
}, | |
child: _jumpButton(i, colors[i]), | |
), | |
], | |
), | |
), | |
AnimatedContainer( | |
margin: EdgeInsets.only( | |
left: 4, | |
top: sectionsPassed * buttonHeight, | |
), | |
duration: const Duration( | |
milliseconds: 150, | |
) /**SHORT_DURATION */, | |
curve: Curves.easeOut, | |
width: 12, | |
decoration: BoxDecoration( | |
color: Colors.grey, | |
borderRadius: BorderRadius.circular(3)), | |
height: buttonHeight, | |
), | |
], | |
) | |
], | |
), | |
), | |
), | |
), | |
), | |
), | |
], | |
), | |
); | |
} | |
Widget _jumpButton(int index, Color color) { | |
return Container( | |
height: buttonHeight, | |
width: buttonWidth, | |
decoration: BoxDecoration( | |
color: color, | |
border: Border.all( | |
color: completed[index] ? Colors.green : Colors.white, | |
width: completed[index] ? 8 : 1, | |
), | |
), | |
child: Center(child: Text('Go to section $index')), | |
); | |
} | |
Widget _section({required int index}) { | |
final hasBox = Random(colors[index].hashCode).nextDouble() > 0.7; | |
const boxHeight = 200.0; | |
var width = 684.0 /**WEB_LAYOUT_CONTENT_WIDTH*/; | |
if (hasBox) width += 330 /**ORDER_TOOL_SIDE_MENU_WIDTH */ + 24; | |
// Insets.insets5; | |
return Column( | |
children: [ | |
// Necessary to ensure the alignment is always the same | |
SizedBox( | |
height: sectionSpacing, | |
key: keys[index], | |
), | |
SizedBox( | |
height: 700, | |
width: width, | |
child: Row( | |
crossAxisAlignment: CrossAxisAlignment.start, | |
children: [ | |
SizedBox( | |
width: 684 /**WEB_LAYOUT_CONTENT_WIDTH */, | |
child: Container( | |
padding: const EdgeInsets.all(24), | |
decoration: BoxDecoration( | |
color: colors[index], | |
), | |
child: Column( | |
children: [ | |
Text('Section $index'), | |
Text('Description of section $index'), | |
TextButton( | |
onPressed: () => setState( | |
() => completed[index] = !completed[index], | |
), | |
child: Text( | |
completed[index] | |
? 'The section is completed!' | |
: 'Complete section', | |
), | |
), | |
], | |
), | |
), | |
), | |
if (hasBox) | |
Padding( | |
padding: const EdgeInsets.only(left: 24 /**Insets.insets5 */), | |
child: SizedBox( | |
width: 330 /**ORDER_TOOL_SIDE_MENU_WIDTH */, | |
height: boxHeight, | |
child: Container( | |
padding: const EdgeInsets.all(24), | |
decoration: BoxDecoration( | |
color: colors[index], | |
), | |
child: const Column( | |
children: [ | |
Text('Im a box'), | |
Text('yay'), | |
], | |
), | |
), | |
), | |
), | |
], | |
), | |
), | |
], | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment