Describe the bug
scrollToIndex is not working when defining SmartRefresher as parent of SingleChildScrollView. scrollToIndexis working as expected wihout SmartRefresher as parent of SingleChildScrollView.
Reproduction code
Code working as expected when no SmartRefresher is defined as parent of SingleChildScrollView:
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:scroll_to_index/scroll_to_index.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Scroll To Index Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Scroll To Index Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final scrollDirection = Axis.vertical;
late AutoScrollController controller;
int count = 2;
@override
void initState() {
super.initState();
controller = AutoScrollController(
viewportBoundaryGetter: () =>
Rect.fromLTRB(0, 0, 0, MediaQuery.of(context).padding.bottom),
axis: scrollDirection);
controller.scrollToIndex(1, preferPosition: AutoScrollPosition.begin);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: SingleChildScrollView(
controller: controller,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.end,
children: _buildChildren(),
),
),
);
}
@override
void dispose() {
super.dispose();
controller.dispose();
}
Widget _wrapScrollTag(
{required int index,
required AutoScrollController controller,
required Widget child}) =>
AutoScrollTag(
key: ValueKey(index),
controller: controller,
index: index,
child: child);
List<Widget> _buildChildren() {
List<Widget> widgets = [];
for (int i = 0; i < count; i++) {
widgets.add(_wrapScrollTag(
index: i,
controller: controller,
child: Container(
height: 520.0,
width: 400.0,
color: i.isEven ? Colors.yellow : Colors.green,
padding:
new EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0),
child: Text(i.toString()))));
}
return widgets;
}
}
Code not working as expected when SmartRefresher is defined as parent of SingleChildScrollView:
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:scroll_to_index/scroll_to_index.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Scroll To Index Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Scroll To Index Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final scrollDirection = Axis.vertical;
final RefreshController _refreshController = RefreshController();
late AutoScrollController controller;
int count = 2;
@override
void initState() {
super.initState();
controller = AutoScrollController(
viewportBoundaryGetter: () =>
Rect.fromLTRB(0, 0, 0, MediaQuery.of(context).padding.bottom),
axis: scrollDirection);
controller.scrollToIndex(1, preferPosition: AutoScrollPosition.begin);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: SmartRefresher(
controller: _refreshController,
enablePullDown: false,
enablePullUp: true,
onLoading: _onLoading,
child: SingleChildScrollView(
controller: controller,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.end,
children: _buildChildren(),
),
)),
);
}
@override
void dispose() {
super.dispose();
controller.dispose();
_refreshController.dispose();
}
Widget _wrapScrollTag(
{required int index,
required AutoScrollController controller,
required Widget child}) =>
AutoScrollTag(
key: ValueKey(index),
controller: controller,
index: index,
child: child);
void _onLoading() {
_refreshController.loadComplete();
setState(() {
count++;
});
}
List<Widget> _buildChildren() {
List<Widget> widgets = [];
for (int i = 0; i < count; i++) {
widgets.add(_wrapScrollTag(
index: i,
controller: controller,
child: Container(
height: 520.0,
width: 400.0,
color: i.isEven ? Colors.yellow : Colors.green,
padding:
new EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0),
child: Text(i.toString()))));
}
return widgets;
}
}
To Reproduce
Steps to reproduce the behavior:
- Load the page
Expected behavior
scrollToIndex should take us to the second container.
Flutter Version:
juancarlos@juancarlos-XPS-15-7590:~/AndroidStudioProjects/solon_flutter_app$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.2.0, on Linux, locale en_US.UTF-8)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.1)
[✓] Connected device (2 available)
• No issues found!
Dependencies:
pull_to_refresh: ^2.0.0
scroll_to_index: ^2.0.0
Describe on which device you found the bug:
Android 11 emulator