如何在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,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(
                              ... ))

它现在可以工作了:)