flutter_carousel_slider icon indicating copy to clipboard operation
flutter_carousel_slider copied to clipboard

Expose PageController

Open robertohuertasm opened this issue 5 years ago • 7 comments
trafficstars

This relates to #49 which was closed by the user but I'm not sure why. The thing is that it would be nice to have this exposed, maybe in the carousel controller itself. Just exposing it there via a property.

I would need this in order to allow some scenarios. Currently, the pageChanged callback just sends an int with the page index. But this page index is rounded. So when the page is still not fully changed, we get a change. I would like to get a double, so I could be completely sure that the new page is visible.

I couldn't find a way to do it with the current implementation, but if I had access to the PageController I could listen to its changes and get a double value.

robertohuertasm avatar May 15 '20 11:05 robertohuertasm

After digging a little bit more, I found a way. Basically, you have to extend the class CarouselControllerImpl and expose the _state. Something similar to this:

class CustomCarouselController extends CarouselControllerImpl {
  CarouselState _state;
  CarouselState get state => _state;

  @override
  set state(CarouselState state) {
    _state = state;
    super.state = state;
  }
}

Finally, in order to get access to the page controller you must be sure that the state is ready:

carouselController.onReady.then((_) {
   carouselController.state.pageController.addListener(() {
     print(
         'page changed: ${widget.carouselController.state.pageController.page}');
   });
 });

Although this solution works I guess the point of exposing it and avoid this kind of workarounds would be still valid.

robertohuertasm avatar May 15 '20 11:05 robertohuertasm

Exposing the pagecontroller will also make it easy to use this package with some really cool indicators that require pagecontroller.

Prn-Ice avatar May 19 '20 00:05 Prn-Ice

@robertohuertasm please is it possible you show us a way to implement your solution, i am finding it a bit hard to do. Thanks in advance.

dynacorp avatar Apr 03 '21 04:04 dynacorp

@dynacorp sorry but it's been a while and I've lost context. As far as I remember you could set the carouselController instance of your carouselSlider. The solution was to simply extend from CarouselControllerImpl as shown in my previous comment and then set the controller property to use an instance of your extended class. Hope this helps you.

robertohuertasm avatar Apr 03 '21 10:04 robertohuertasm

It seems that this piece of code no longer works ~in Flutter 2.0 because of some changes in ScrollController~

EDIT: Nope, it's because of something between 2.2.1 and 2.3.0

ncuillery avatar May 04 '21 17:05 ncuillery

Hi, I have same issue. Have any ideal to solve this?

sinhpn92 avatar Feb 13 '22 17:02 sinhpn92

I've tried @robertohuertasm solution and it works perfectly

class CustomCarouselController extends CarouselControllerImpl {
  CarouselState? _state;
  CarouselState? get state => _state;

  @override
  set state(CarouselState? state) {
    _state = state;
    super.state = state;
  }
}

Then on the SmoothPageIndicator package

FutureBuilder(
              future: _carouselController.onReady,
              builder: (context, snapshot) {
                if (snapshot.connectionState == ConnectionState.done) {
                  return Padding(
                    padding: const EdgeInsets.only(bottom: 10.0),
                    child: Align(
                      alignment: Alignment.bottomCenter,
                      child: SmoothPageIndicator(
                        controller: _carouselController.state!.pageController!,
                        count: _carouselController.state!.itemCount!,
                        onDotClicked: (val) {
                          _carouselController.animateToPage(val);
                        },
                        effect: const SlideEffect(
                          activeDotColor: myColor,
                          paintStyle: PaintingStyle.stroke,
                          spacing: 10,
                          dotWidth: 20,
                          dotColor: Colors.white,
                          strokeWidth: 2,
                        ),
                      ),
                    ),
                  );
                }
                return const SizedBox.shrink();
              },
            ),

harlanx avatar Jul 10 '23 06:07 harlanx