0

Rewriting for clarity and insight. Essentially the issue I'm running into is that when the carousel's items are mapped from state, the carousel is not rebuilt on state change.

Here's a minimal example:

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
//import 'package:carousel_slider/carousel_slider.dart';
import 'package:carousel_slider_plus/carousel_slider_plus.dart';

class Playground extends HookConsumerWidget {
  
  @override
  Widget build(BuildContext context, WidgetRef ref) {

    CarouselControllerPlus _controller = CarouselControllerPlus();
    ValueNotifier<List<int>> slides = useState([1,2,3]);

    return Padding(
      padding: const EdgeInsets.fromLTRB(0, 100, 0, 0),
      child: Column(
      children: [
        CarouselSlider(
        items: (slides.value).map(
          (v) => GestureDetector(
            onLongPress: v==1 ? (){
              print("jumping to last slide");
              _controller.jumpToPage(slides.value.length-1);
            } : (){},
            child: Container(
              width: 500,
              color: v==1 ? Colors.green : Colors.grey,
              child: Text(
                v.toString(),
                style: TextStyle(fontSize: 16.0),
              )
            ),
          ),
        ).toList(),
        controller: _controller,
        options: CarouselOptions(
          autoPlay: false,
          enlargeCenterPage: true,
          viewportFraction: 0.9,
          aspectRatio: 2.0,
          initialPage: 2,
        ),
        ),
        GestureDetector(
          onTap: () => _controller.nextPage(
              duration: Duration(milliseconds: 300), curve: Curves.linear),
          child: Container(
            height: 50,
            width: 50,
            child: Text(
              '→',
              style: TextStyle(fontSize: 30.0),
            ),
          ),
        ),
        GestureDetector(
          onTap: (){
            print("adding slide");
            final temp = slides.value; // use a temp variable to trigger a rebuild
            temp.add(temp.length+1);
            print(slides.value);
            slides.value = temp;
          },
          child: Container(
            height: 50,
            width: 50,
            child: Text(
              '+',
              style: TextStyle(fontSize: 30.0),
            ),
          ),
        ),
      ],
    )
    );
  }
}

For viewers of the previous post (carousel throwing null error on nextPage or jumpToPage), essentially what's happening is that the new addition is added to state but the carousel doesn't update, so attempting to use the controller to modify carousel position throws a null error.

Note: this applies for both carousel_slider and carousel_slider_plus.

To recreate the null exception error, simply add a few pages using the "+" button, then hot refresh and attempt to use the "->" or longpress on slide 1.

I believe the reason it didn't work for me previously with constant values last time was something along the lines of that I was hot reloading and not refreshing, so the state values from my previous experiments persisted.

5
  • Check the logging for a the crash, it will tell you (and us) what line you are using some variable when it is null.
    – petey
    Commented Jul 4 at 18:32
  • seems working for me, tried without hook widget Commented Jul 4 at 19:14
  • Can you please try to use carousel_slider_plus and check if this issue still occurs? The original carousel_slider is not maintained anymore. Commented Jul 5 at 5:21
  • @KishanDhankecha unfortunately didn't fix the issue, but I did do some more digging into the root cause
    – liamhp
    Commented Jul 9 at 2:52
  • Going to implement using traditional state instead of hooks tomorrow, will update here accordingly
    – liamhp
    Commented Jul 9 at 2:56

0

Browse other questions tagged or ask your own question.