Search code examples
fluttercontrollerblocrxdartflutter-pageview

PageController not set properly within the PageView module in Flutter. Positions not empty error popping up


I started programming using the Flutter framework and immediately noticed an odd issue popping up (see below for more info).

The problem occurs when: After returning to the MainScreen and trying to change from the PageView index by pressing on a button to switch from screens within the PageView, I get this error:

[ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: 'package:flutter/src/widgets/scroll_controller.dart': Failed assertion: line 110 pos 12: '_positions.isNotEmpty': ScrollController not attached to any scroll views.

This is my MainScreen:

class MainScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => MainScreenState();
}

class MainScreenState extends State<MainScreen> {
  PageController _controller;

  void _onLoad() {
    _controller = PageController();
    ShareBloc.getInstance().pageViewIndexStream.listen((index) {
      _controller.animateToPage(index,
          duration: Duration(milliseconds: 200), curve: Curves.easeInOut);
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    _onLoad();

    return PageView(
      controller: _controller,
      physics: NeverScrollableScrollPhysics(),
      children: [
        FirstScreen(),
        SecondScreen(),
      ],
    );
  }
}

This is my RxDart Sharable file:

import 'package:rxdart/rxdart.dart';

class ShareBloc {
  static ShareBloc _instance;
  BehaviorSubject<dynamic> _subjectCounter;

  static ShareBloc getInstance() {
    if (_instance == null) _instance = ShareBloc();
    return _instance;
  }

  ShareBloc() {
    _subjectCounter = new BehaviorSubject<dynamic>();
  }

  Stream<dynamic> get getStream => pageViewIndexStream.stream;

  void onShare(dynamic data) {
    _subjectCounter.sink.add(data);
  }

  void dispose() {
    if (_subjectCounter != null) {
      _subjectCounter.close();
      _instance = null;
    }
  }
}

Can someone tell me what I am doing wrong here?


Solution

  • The proper way to fix this issue for me was to wrap this part:

    ShareBloc.getInstance().pageViewIndexStream.listen((index) {
          _controller.animateToPage(index,
              duration: Duration(milliseconds: 200), curve: Curves.easeInOut);
        });
    

    With:

    ShareBloc.getInstance().pageViewIndexStream.listen((index) {
          if (_controller.hasClients) { // <-- this is the fix!
            _controller.animateToPage(index,
                duration: Duration(milliseconds: 200), curve: Curves.easeInOut);
          }
        });