Code sample
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final _scrollController = ScrollController();
int _childCount = 50;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('app bar'),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
_childCount++;
});
WidgetsBinding.instance?.scheduleFrameCallback(
(_) => WidgetsBinding.instance?.addPostFrameCallback(
(_) => _scrollController.animateTo(
_scrollController.position.maxScrollExtent,
duration: const Duration(milliseconds: 200),
curve: Curves.easeIn,
),
),
);
},
child: const Icon(Icons.arrow_downward),
),
body: SafeArea(
child: RefreshIndicator(
onRefresh: () {
return Future.delayed(const Duration(seconds: 1));
},
child: ListView.builder(
controller: _scrollController,
padding: EdgeInsets.zero,
itemCount: _childCount,
itemBuilder: (context, index) {
return ListTile(
title: Center(
child: Text('ListTile $index'),
),
);
},
),
),
),
);
}
}
WidgetsBinding.instance?.scheduleFrameCallback(
(_) => WidgetsBinding.instance?.addPostFrameCallback(
(_) {
_scrollController.jumpTo(
_scrollController.offset + Tolerance.defaultTolerance.distance,
);
WidgetsBinding.instance?.addPostFrameCallback(
(_) => _scrollController.animateTo(
_scrollController.position.maxScrollExtent,
duration: const Duration(milliseconds: 200),
curve: Curves.easeIn,
),
);
},
),
);
WidgetsBinding.instance?.scheduleFrameCallback(
(_) => WidgetsBinding.instance?.addPostFrameCallback(
(_) async {
while (!nearEqual(
_scrollController.position.maxScrollExtent,
_scrollController.offset,
Tolerance.defaultTolerance.distance,
)) {
await _scrollController.animateTo(
_scrollController.position.maxScrollExtent,
duration: const Duration(milliseconds: 200),
curve: Curves.linear,
);
}
},
),
);
Steps to Reproduce
flutter runon the code sampleExpected results:
Actual results:
2021-12-09.18.45.56.mov
Code sample
Logs
notice
2021-12-09.19.03.46.mov
2021-12-09.19.03.12.mov
workaround
jumpTobeforeanimateToand wrapanimateToinaddPostFrameCallback