This could also be done in a stateless widget, by triggering it in the build method. Used addPostFrameCallback
to ensure that the scrolling is done after the rendering is done. You'll need to add back state management for the value
of the choice. But then you have a choice of using GetX, StatefulWidget or any other.
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key? key, this.title}) : super(key: key);
final String? title;
static final List<GlobalKey> _key = List.generate(20, (index) => GlobalKey());
final List<Widget> buttons = List.generate(
20,
(index) => ElevatedButton(
onPressed: () {},
style: ButtonStyle(backgroundColor: MaterialStateProperty.resolveWith((_)=> index % 2 == 0 ? Colors.lightGreen : Colors.orange)),
child: Text("Button No # ${index + 1}", key: _key[index]),
),
);
@override
Widget build(BuildContext context) {
final thisWidget = Scaffold(
appBar: AppBar(
title: Text(title!),
),
body: Column(
children: [
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: buttons,
),
),
DropdownButton(
value: 0,
items: List.generate(
20,
(index) => DropdownMenuItem(
value: index,
child: Text("Goto Button # ${index + 1}")),
),
onChanged: (value) {
if (value != null) {
WidgetsBinding.instance
.addPostFrameCallback((_) => Scrollable.ensureVisible(_key[value].currentContext!));
}
},
)
],
),
);
WidgetsBinding.instance
.addPostFrameCallback((_) => Scrollable.ensureVisible(_key[15].currentContext!));
return thisWidget;
}
}
Scrollable.ensureVisible
method then – Darcydarda