likes
comments
collection
share

【Flutter小技巧10】--- Flutter图片浏览器组件(支持左右滑动,放大缩小)

作者站长头像
站长
· 阅读数 7

📃 需求是学习技术最有效的动力

一、前言:结合上篇文章,写了图片显示组件之后,自然要有图片浏览器,放大缩小,左右滑动,点击后关闭图片浏览器,图片缓存。主要使用了 extended_image 插件 效果图如下:

【Flutter小技巧10】--- Flutter图片浏览器组件(支持左右滑动,放大缩小)

【Flutter小技巧10】--- Flutter图片浏览器组件(支持左右滑动,放大缩小)

二、实现步骤 1、创建一个page,创建一个手势组件,为了点击关闭当前图片浏览器 2、创建Stack可叠加组件,滑动的图片张数和图片总张数。 3、组合完成 4、对外参数,图片数组,初始化选择第几张图片

三、具体实现 1、创建一个手势组件,为了点击关闭当前图片浏览器,使用ExtendedImageGesturePageView显示图片,支持放大,缩小。

GestureDetector(
onTap: () {
 Get.back();
},
child: Container(
 color: Colors.transparent,
 child: ExtendedImageGesturePageView.builder(
   itemBuilder: (BuildContext context, int index) {
     var item = imagesTest[index];
     Widget image = ExtendedImage.network(
       item,
       fit: BoxFit.contain,
       mode: ExtendedImageMode.gesture,
     );
     image = Container(
       child: image,
       padding: EdgeInsets.all(5.0),
     );
     if (index == currentIndex) {
       return Hero(
         tag: item + index.toString(),
         child: image,
       );
     } else {
       return image;
     }
   },
   itemCount: imagesTest.length,
   onPageChanged: (int index) {
     setState(() {
       currentIndex = index;
     });
   },
   // controller: PageController(
   //   initialPage: widget.currentIndex,
   // ),
   scrollDirection: Axis.horizontal,
 ),
),
),

2、创建Stack可叠加组件,滑动的图片张数和图片总张数。

Stack(
  children: <Widget>[
    GestureDetector(
      onTap: () {
        Get.back();
      },
      child: Container(
        color: Colors.transparent,
        child: ExtendedImageGesturePageView.builder(
          itemBuilder: (BuildContext context, int index) {
            var item = imagesTest[index];
            Widget image = ExtendedImage.network(
              item,
              fit: BoxFit.contain,
              mode: ExtendedImageMode.gesture,
            );
            image = Container(
              child: image,
              padding: EdgeInsets.all(5.0),
            );
            if (index == currentIndex) {
              return Hero(
                tag: item + index.toString(),
                child: image,
              );
            } else {
              return image;
            }
          },
          itemCount: imagesTest.length,
          onPageChanged: (int index) {
            setState(() {
              currentIndex = index;
            });
          },
          // controller: PageController(
          //   initialPage: widget.currentIndex,
          // ),
          scrollDirection: Axis.horizontal,
        ),
      ),
    ),
    Positioned(
      //图片index显示
      top: MediaQuery.of(context).padding.top + 15,
      width: MediaQuery.of(context).size.width,
      child: Center(
        child: Text("${currentIndex + 1}/${imagesTest.length}",
            style: TextStyle(color: Colors.white, fontSize: 16)),
      ),
    ),
  ],
),

3、组合完成。也就是具体的完整代码实现。可直接复用。

class PhotoBrowsePage extends StatefulWidget {
  final List<String>? images;
  final int initIndex;
  const PhotoBrowsePage({
    Key? key,
    this.images,
    this.initIndex = 0,
  }) : super(key: key);

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

class _PhotoBrowsePageState extends State<PhotoBrowsePage> {
  PageController? controller;
  int currentIndex = 0;
  /// 测试
  List<String> imagesTest = <String>[    'https://photo.tuchong.com/14649482/f/601672690.jpg',    'https://photo.tuchong.com/17325605/f/641585173.jpg',    'https://photo.tuchong.com/3541468/f/256561232.jpg',    'https://photo.tuchong.com/16709139/f/278778447.jpg',    'https://photo.tuchong.com/15195571/f/233361383.jpg',    'https://photo.tuchong.com/5040418/f/43305517.jpg',    'https://photo.tuchong.com/3019649/f/302699092.jpg'  ];
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    // widget.images = images;
    currentIndex = widget.initIndex;
    controller = PageController(initialPage: currentIndex);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      body: Stack(
        children: <Widget>[
          GestureDetector(
            onTap: () {
              Get.back();
            },
            child: Container(
              color: Colors.transparent,
              child: ExtendedImageGesturePageView.builder(
                itemBuilder: (BuildContext context, int index) {
                  var item = imagesTest[index];
                  Widget image = ExtendedImage.network(
                    item,
                    fit: BoxFit.contain,
                    mode: ExtendedImageMode.gesture,
                  );
                  image = Container(
                    child: image,
                    padding: EdgeInsets.all(5.0),
                  );
                  if (index == currentIndex) {
                    return Hero(
                      tag: item + index.toString(),
                      child: image,
                    );
                  } else {
                    return image;
                  }
                },
                itemCount: imagesTest.length,
                onPageChanged: (int index) {
                  setState(() {
                    currentIndex = index;
                  });
                },
                // controller: PageController(
                //   initialPage: widget.currentIndex,
                // ),
                scrollDirection: Axis.horizontal,
              ),
            ),
          ),
          Positioned(
            //图片index显示
            top: MediaQuery.of(context).padding.top + 15,
            width: MediaQuery.of(context).size.width,
            child: Center(
              child: Text("${currentIndex + 1}/${imagesTest.length}",
                  style: TextStyle(color: Colors.white, fontSize: 16)),
            ),
          ),
        ],
      ),
    );
  }
}

四、记录点点滴滴,只为记录自己曾经做过。下一期,列表单双排切换。