在 Flutter 中,我们可以通过将
PrimaryScrollController
从根 Scaffold
传递到 ScrollView
,在点击状态栏后滚动到顶部。但是,我的应用程序有一个带有 4 个选项卡的底部导航,每个选项卡都包含一个 ScrollView。当我点击状态栏时,所有 4 个选项卡都会滚动到顶部,但我只想滚动当前选定的选项卡。
按照这个帖子,似乎没有官方的方法可以做到这一点 https://github.com/flutter/flutter/issues/85603#issuecomment-876798161
是否有任何解决方法或替代方法可以在点击状态栏后仅将选定的选项卡滚动到顶部?
我不久前遇到了同样的问题,并提出了自己的解决方案。它可能不完全是您正在寻找的,但它对我来说非常有效。
这里是示例应用程序代码,您可以根据需要进行测试:
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',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _currentIndex = 0;
final ScrollController scrollController = ScrollController();
List<double> offsets = [];
@override
void initState() {
// Number of options in the bottomNavigationBar
offsets.addAll([0, 0, 0]);
super.initState();
}
final List<Widget> _pages = [
SingleChildScrollView(
child: Column(
children: List.generate(
20, (index) => ListTile(title: Text('Home Item $index'))),
),
),
SingleChildScrollView(
child: Column(
children: List.generate(
20, (index) => ListTile(title: Text('Search Item $index'))),
),
),
SingleChildScrollView(
child: Column(
children: List.generate(
20, (index) => ListTile(title: Text('Profile Item $index'))),
),
),
];
void _scrollToTop() {
scrollController.jumpTo(0);
}
void _onTabTapped(int index) {
// Select the offset for the selected page
offsets[_currentIndex] = scrollController.offset;
setState(() {
_currentIndex = index;
scrollController.jumpTo(offsets[index]);
});
}
@override
Widget build(BuildContext context) {
return PrimaryScrollController(
controller: scrollController,
child: Scaffold(
appBar: AppBar(
title: Text('BottomNavigationBar + Scroll'),
),
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: _onTabTapped,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
label: 'Search',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Profile',
),
],
),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: _scrollToTop,
child: Icon(Icons.arrow_upward),
tooltip: 'Scroll to Top',
),
],
),
),
);
}
}