I am creating a simple web portfolio to have hand-on practice in flutter. I was wondering how other website work when we click on home/about/contact button the web scroll to that specific widget.
I tried to do this but didn't get it how to implement this functionality
Code example will be helpful and will be appreciated as upvote.
CodePudding user response:
you can give global key to the widget you want to scroll to e.g
final dataKey = new GlobalKey();
assign it to the widget
Container(key:dataKey);
and then on the button onpressed write this code
onPressed: (){
Scrollable.ensureVisible(dataKey.currentContext);
}
CodePudding user response:
you could use this package scroll_to_id
and here is an exemple made by github@yusukeinouehatchout
import 'package:flutter/material.dart';
import 'package:scroll_to_id/scroll_to_id.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
ScrollToId? scrollToId;
final ScrollController scrollController = ScrollController();
List<Color> _colorList = [
Colors.green,
Colors.red,
Colors.yellow,
Colors.blue
];
void _scrollListener() {
print(scrollToId!.idPosition());
}
@override
void initState() {
super.initState();
/// Create ScrollToId instance
scrollToId = ScrollToId(scrollController: scrollController);
scrollController.addListener(_scrollListener);
}
/// Generate 10 Container
/// Case [Axis.horizontal] set buildStackHorizontal() to body
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Scroll to id',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: const Text('Scroll to id'),
),
body: buildStackVertical(),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.navigate_next),
onPressed: () {
scrollToId!.animateToNext(
duration: Duration(milliseconds: 500), curve: Curves.ease);
},
),
),
);
}
/// [Axis.vertical]
/// https://raw.githubusercontent.com/wiki/yusukeinouehatchout/scroll_to_id/gif/scroll_to_id_vertical.gif
Widget buildStackVertical() {
return Stack(
alignment: Alignment.topRight,
children: [
InteractiveScrollViewer(
scrollToId: scrollToId,
children: List.generate(10, (index) {
return ScrollContent(
id: '$index',
child: Container(
alignment: Alignment.center,
width: double.infinity,
height: 200,
child: Text(
'$index',
style: TextStyle(color: Colors.white, fontSize: 50),
),
color: _colorList[index % _colorList.length],
),
);
}),
),
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.white, width: 3),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: List.generate(10, (index) {
return GestureDetector(
child: Container(
width: 100,
alignment: Alignment.center,
height: 50,
child: Text(
'$index',
style: TextStyle(color: Colors.white),
),
color: _colorList[index % _colorList.length],
),
onTap: () {
/// scroll with animation
scrollToId!.animateTo('$index',
duration: Duration(milliseconds: 500),
curve: Curves.ease);
/// scroll with jump
// scrollToId.jumpTo('$index');
},
);
}),
),
)
],
);
}
/// [Axis.horizontal]
/// https://raw.githubusercontent.com/wiki/yusukeinouehatchout/scroll_to_id/gif/scroll_to_id_horizontal.gif
Widget buildStackHorizontal() {
return Column(
children: [
Container(
width: double.infinity,
decoration: BoxDecoration(
border: Border.all(color: Colors.white, width: 3),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: List.generate(10, (index) {
return Expanded(
child: GestureDetector(
child: Container(
alignment: Alignment.center,
height: 80,
child: Text(
'$index',
style: TextStyle(color: Colors.white),
),
color: _colorList[index % _colorList.length],
),
onTap: () {
/// scroll with animation
scrollToId!.animateTo('$index',
duration: Duration(milliseconds: 500),
curve: Curves.ease);
/// scroll with jump
// scrollToId.jumpTo('$index');
},
),
);
}),
),
),
Expanded(
child: InteractiveScrollViewer(
scrollToId: scrollToId,
scrollDirection: Axis.horizontal,
children: List.generate(10, (index) {
return ScrollContent(
id: '$index',
child: Container(
alignment: Alignment.center,
width: 200,
child: Text(
'$index',
style: TextStyle(color: Colors.white, fontSize: 50),
),
color: _colorList[index % _colorList.length],
),
);
}),
),
),
],
);
}
}