'ScrollController attached to multiple scroll views Failed assertion: line 109 pos 12: '_positions.length == 1'
I make error when using animateToPage
ScrollController attached to multiple scroll views. 'package:flutter/src/widgets/scroll_controller.dart': Failed assertion: line 109 pos 12: '_positions.length == 1'
I try to use _pageController.hasClients but it not working.
Please have a look in my code-
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
@override
_MyAppState createState() =>_MyAppState();
}
class _MyAppState extends State {
PageController _pageController;
ScrollController _scrollController;
double offset = 0.0;
@override
void initState(){
super.initState();
_pageController = PageController(initialPage: 0);
_scrollController = ScrollController();
_scrollController.addListener(this.swapPageListener);
}
void swapPageListener() {
offset = _scrollController.offset;
_pageController.hasClients
if (offset > _scrollController.position.maxScrollExtent + 100) {
_pageController.animateToPage(1, duration: Duration(milliseconds: 500), curve: Curves.ease);
}
if (offset < _scrollController.position.minScrollExtent - 100) {
_pageController.animateToPage(0, duration: Duration(milliseconds: 500), curve: Curves.ease);
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: PageView.builder(
controller: _pageController,
scrollDirection: Axis.vertical,
itemCount: 2,
physics: PageScrollPhysics(),
itemBuilder: (context, idx) {
if(idx == 0) {
return _screen1();
} else {
return _screen2();
}
}
),
),
);
}
Widget _screen1() {
return SingleChildScrollView(
physics: BouncingScrollPhysics(),
controller: _scrollController,
child: Container(
height: 1000.0,
color: Colors.red,
child: Center(
child: Text('screen 1'),
),
),
);
}
Widget _screen2() {
return SingleChildScrollView(
physics: BouncingScrollPhysics(),
controller: _scrollController,
child: Container(
height: 1000.0,
color: Colors.green,
child: Center(
child: Text('screen 2'),
),
),
);
}
}
Thanks in advance
Hello, I have found the solution to this problem
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
PageController _pageController;
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState(){
super.initState();
_pageController = PageController(initialPage: 0);
}
// @override
// void dispose() {
// super.dispose();
// _pageController.dispose();
// }
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: PageView.builder(
controller: _pageController,
scrollDirection: Axis.vertical,
itemCount: 2,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, idx) {
return Screen(pageKey: idx,);
}
),
),
);
}
}
class Screen extends StatefulWidget {
Screen({Key key, this.pageKey}) : super(key: key);
final pageKey;
@override
_ScreenState createState() => _ScreenState();
}
class _ScreenState extends State<Screen> {
ScrollController _scrollController;
@override
void initState(){
super.initState();
_scrollController = ScrollController();
_scrollController.addListener(this.swapPageListener);
}
void swapPageListener() {
if (_scrollController.offset > _scrollController.position.maxScrollExtent + 100) {
_pageController.animateToPage(1, duration: Duration(milliseconds: 400), curve: Curves.easeInOut);
}
if (_scrollController.offset < _scrollController.position.minScrollExtent - 100) {
_pageController.animateToPage(0, duration: Duration(milliseconds: 400), curve: Curves.easeInOut);
}
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
physics: BouncingScrollPhysics(),
controller: _scrollController,
child: Container(
height: 1000.0,
color: Colors.green,
child: Center(
child: Text('screen ${widget.pageKey}'),
),
),
);
}
}
Solution 1:[1]
please check out your solution
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State {
PageController _pageController;
ScrollController _scrollController;
double offset = 0.0;
@override
void initState(){
super.initState();
_pageController = PageController(initialPage: 0);
_scrollController = ScrollController();
_scrollController.addListener(this.swapPageListener);
}
void swapPageListener() {
offset = _scrollController.offset;
setState(() {
_pageController.hasClients;
if (offset > _scrollController.position.maxScrollExtent + 100) {
_pageController.animateToPage(1, duration: Duration(milliseconds: 500), curve: Curves.ease);
}
if (offset <_scrollController.position.minScrollExtent - 100) {
_pageController.animateToPage(0, duration: Duration(milliseconds: 500), curve: Curves.ease);
}
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: PageView.builder(
controller: _pageController,
scrollDirection: Axis.vertical,
pageSnapping: true,
itemCount: 2,
physics: PageScrollPhysics(),
itemBuilder: (context, idx) {
if(idx == 0) {
return _screen1();
} else {
return _screen2();
}
}
),
),
);
}
Widget _screen1() {
return SingleChildScrollView(
physics: BouncingScrollPhysics(),
controller: _scrollController,
child: Container(
height: 1000.0,
color: Colors.red,
child: Center(
child: Text('screen 1'),
),
),
);
}
Widget _screen2() {
return SingleChildScrollView(
physics: BouncingScrollPhysics(),
controller: _scrollController,
child: Container(
height: 1000.0,
color: Colors.green,
child: Center(
child: Text('screen 2'),
),
),
);
}
}
Solution 2:[2]
Here is the answer provided by me which is working fine
Check out the answer here.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |