Flutter Using Controller from a child widget

1,196

Solution 1

In the imageSelector widget create a variable to access the controller like:

class imageSelector extends StatelessWidget {
final CarouselController _controller;
imageSelector(this._controller);

now pass the controller value as a parameter when you are calling imageSelector like:

imageSelector(_controller)

So your corrected code would be:

For ManuallyControlledSlider:

class ManuallyControlledSlider extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _ManuallyControlledSliderState();
  }
}

class _ManuallyControlledSliderState extends State<ManuallyControlledSlider> {
  final CarouselController _controller = CarouselController();

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Manually controlled slider')),
      body: Column(
        children: <Widget>[
          CarouselSlider(
            items: imageSliders,
            options: CarouselOptions(enlargeCenterPage: true, aspectRatio: 16/9),
            carouselController: _controller,
          ),
          imageSelector(_controller), //Corrected

        ],
      ),
    );
  }
}

And the child:

class imageSelector extends StatelessWidget {
final CarouselController _controller;
imageSelector(this._controller);
  @override
  Widget build(BuildContext context) {
return Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Flexible(
                child: RaisedButton(
                  onPressed: () => _controller.previousPage(
                      duration: Duration(milliseconds: 300), curve: Curves.linear),
                  child: Text('←'),
                ),
              ),
              Flexible(
                child: RaisedButton(
                  onPressed: () => _controller.nextPage(
                      duration: Duration(milliseconds: 300), curve: Curves.linear),
                  child: Text('→'),
                ),
              ),
              ...Iterable<int>.generate(imgList.length).map(
                (int pageIndex) => Flexible(
                  child: RaisedButton(
                    onPressed: () => _controller.animateToPage(
                        pageIndex,
                        duration: Duration(milliseconds: 300),
                        curve: Curves.linear),
                    child: Text("$pageIndex"),
                  ),
                ),
              ),
            ],
          );
}

Solution 2

You can pass the _controller as an optional parameter to imageSelector.

Share:
1,196
CarlosSR
Author by

CarlosSR

bring data!

Updated on December 19, 2022

Comments

  • CarlosSR
    CarlosSR over 1 year

    I'm fairly new to Flutter and a few days ago I run into carousel_slider package.

    One of the examples provided in the doc is a Manually Controlled Slider, but when I change how the widget is build I lose the onPressed ability since the child widget does not know what the _controller is. Which is the proper way to pass info from the state to the child so the child can call _controller.nextPage(), _controller.previousPage() or _controller.animateToPage() ?

    class ManuallyControlledSlider extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return _ManuallyControlledSliderState();
      }
    }
    
    class _ManuallyControlledSliderState extends State<ManuallyControlledSlider> {
      final CarouselController _controller = CarouselController();
    
      @override
      void initState() {
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text('Manually controlled slider')),
          body: Column(
            children: <Widget>[
              CarouselSlider(
                items: imageSliders,
                options: CarouselOptions(enlargeCenterPage: true, aspectRatio: 16/9),
                carouselController: _controller,
              ),
              imageSelector(), //MAIN ISSUE
    
            ],
          ),
        );
      }
    }
    

    The child definition:

    class imageSelector extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
    return Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  Flexible(
                    child: RaisedButton(
                      onPressed: () => _controller.previousPage(
                          duration: Duration(milliseconds: 300), curve: Curves.linear),
                      child: Text('←'),
                    ),
                  ),
                  Flexible(
                    child: RaisedButton(
                      onPressed: () => _controller.nextPage(
                          duration: Duration(milliseconds: 300), curve: Curves.linear),
                      child: Text('→'),
                    ),
                  ),
                  ...Iterable<int>.generate(imgList.length).map(
                    (int pageIndex) => Flexible(
                      child: RaisedButton(
                        onPressed: () => _controller.animateToPage(
                            pageIndex,
                            duration: Duration(milliseconds: 300),
                            curve: Curves.linear),
                        child: Text("$pageIndex"),
                      ),
                    ),
                  ),
                ],
              );
    }