如何在 Flutter 中实现手动轮播滑块?

How to Implement a manual carousel slider in Flutter?

我正在创建一个包含鞋子图片的产品图片轮播,用户可以在其中通过选择不同的颜色来更改要查看的图片。
用户可以手动滚动图像而不会出现问题,但是当我尝试手动更改显示的轮播图像时,只有指示器发生变化,但图像仍保留在第一张图像上。

class DetailsPage extends StatefulWidget {
  final String url;
  final String title;
  final int index;
  DetailsPage({this.url, this.title, this.index});

  @override
  _DetailsPageState createState() => _DetailsPageState();
}

class _DetailsPageState extends State<DetailsPage> {
  List imgList = [
    'https://i.dlpng.com/static/png/6838599_preview.png',
    'https://www.manelsanchez.pt/uploads/media/images/nike-air-force-max-ii-blue-fury-18.jpg',
    'https://www.vippng.com/png/detail/30-302339_nike-women-running-shoes-png-image-transparent-background.png',
  ];
  int _current = 0;
  String selected = "grey";

  List<T> map<T>(List list, Function handler) {
    List<T> result = [];
    for (var i = 0; i < list.length; i++) {
      result.add(handler(i, list[i]));
    }
    return result;
  }

  final CarouselController _buttonCarouselController = CarouselController();


  @override
  Widget build(BuildContext context) {   
    return Scaffold(
        backgroundColor: Theme.of(context).canvasColor,
        appBar: AppBar(
            title: Center(
              child: Text(
                'Details',
                style: TextStyle(
                    fontFamily: 'OpenSansLight',
                    fontSize: 26,
                    color: Theme.of(context).textTheme.headline1.color),
              ),
            ),
         
        body: ListView(
                    mainAxisSize: MainAxisSize.min,
                    children: <Widget>[
                     //Carousel Slider
                      CarouselSlider.builder(
                          options: CarouselOptions(
                              carouselController: _buttonCarouselController,
                              height: 200.0,
                              enlargeCenterPage: true,
                              enlargeStrategy: CenterPageEnlargeStrategy.height,
                              initialPage: 0,
                              reverse: false,
                              autoPlay: false,
                              enableInfiniteScroll: false,
                              scrollDirection: Axis.horizontal,
                              onPageChanged: (index, fn) {
                                setState(() {
                                  _current = index;
                                });
                              }),
                          itemCount: imgList.length,
                          itemBuilder: (BuildContext context, int index) =>
                              Builder(builder: (BuildContext context) {
                            return Image.network(
                              imgList[index],
                              fit: BoxFit.contain,
                            );
                          }),
                        
                      ),
                      SizedBox(height: 10),
                     //Indicator to show current index of images
                      Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: map<Widget>(imgList, (index, url) {
                          return Container(
                            width: 30.0,
                            height: 2.0,
                            margin: EdgeInsets.symmetric(
                                vertical: 10.0, horizontal: 4.0),
                            decoration: BoxDecoration(
                              shape: BoxShape.rectangle,
                              borderRadius: BorderRadius.circular(10.0),
                              color: _current == index
                                  ? Colors.deepPurple
                                  : Colors.grey,
                            ),
                          );
                        }),
                      ),
                    Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: Container(
                          height: 30,
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.start,
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: <Widget>[
                              Text('Color',
                                  style: TextStyle(
                                      fontFamily: 'OpenSansLight',
                                      fontSize: 24)),
                            ],
                          ),
                        ),
                      ),
                      Flexible(
                        fit: FlexFit.loose,
                        child: Container(
                          width: width,
                          height: 120,
                          child: ListView.builder(
                            scrollDirection: Axis.horizontal,
                            itemCount: imgList.length,
                            itemBuilder: (BuildContext context, int index) {
                             //Color selector from images to manually control the carousel 
                             return GestureDetector(
                                onTap: () {
                                  setState(() {
                                    selected = imgList[index];
                                    _current = index;
                                    _buttonCarouselController
                                        .animateToPage(_current);
                                    print('I HAVE SELECTED $selected');
                                  });
                                },
                                child: ColorTicker(
                                  image: imgList[index],
                                  selected: selected == imgList[index],
                                ),
                              );
                            },
                          ),
                        ),
                      ), 
                     ],
                    ),
                   );

颜色代码小工具

class ColorTicker extends StatelessWidget {
  final image;

  final bool selected;
 
  ColorTicker({this.image, this.selected});

  @override
  Widget build(BuildContext context) {
    print(selected);
    return Container( 
      margin: EdgeInsets.all(5),
      width: 100,
      height: 100,
      decoration: BoxDecoration(
          image: DecorationImage(
              fit: BoxFit.scaleDown, image: NetworkImage(image)),
          shape: BoxShape.circle,
          border: selected
              ? Border.all(color: Colors.deepPurple, width: 3)
              : Border.all(color: Colors.grey[500])),
      // color: color.withOpacity(0.7)),

      child: selected
          ? Center(child: Icon(Icons.check, size: 40, color: Colors.deepPurple))
          : Container(),
    );
  }
}

我已尽我所能从文档中获得:https://pub.dev/packages/carousel_slider/example
但是我一直报错

Unhandled Exception: NoSuchMethodError: The getter 'options' was called on null

我为自己的错误感到尴尬。
在滑块的配置中,我把控制器放错了地方。
我将控制器放在 Carousel 选项中,而不是放在 CarouselSlider

CarouselSlider(
               carouselController: _buttonCarouselController,
               options: CarouselOptions(
                              ... ))

现在有效:)