flutter 查看大图

ComSwiper(
context: context,
bannerList: .picList,
onTap: (index) {
print(index);
Navigator.of(context).push(
PageRouteBuilder(
opaque: false, // set to false
pageBuilder: (
___, __, __) => CachedNetworkImage(
imageUrl: ConfigUtil.oss_url +
.picList[index],
imageBuilder: (context, imageProvider) => ImageScreen(
imageProvider: imageProvider,
heroTag: _.picList[index],
mData: .picList,
index: index,
downloadFn: (index) => ImageUtil.savenNetworkImage(
context,
ConfigUtil.oss_url +
.picList[index])),
placeholder: (context, url) => Container(
color: Colors.black,
child: const Center(
child: CircularProgressIndicator(
color: Colors.white))),
errorWidget: (context, url, error) => Container(),
fadeInDuration: const Duration(milliseconds: 0),
),
),
);
},
),

import 'dart:math';

import 'package:extended_image/extended_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:toptongpin/app/res/colors.dart';
import 'package:toptongpin/app/res/styles.dart';

import '../../../../utils/config_util.dart';

typedef DoubleClickAnimationListener = void Function();

class ImageScreen extends StatefulWidget {
  const ImageScreen({
    required this.imageProvider,
    required this.heroTag,
    required this.downloadFn,
    this.mData,
    this.index,
    Key? key,
  }) : super(key: key);

  final ImageProvider imageProvider;
  final String heroTag;
  final  Function downloadFn;
  final List<dynamic>? mData;
  final int? index;

  @override
  State<StatefulWidget> createState() {
    return _ImageScreenState();
  }
}

class _ImageScreenState extends State<ImageScreen>
    with TickerProviderStateMixin {
  Animation<double>? _doubleClickAnimation;
  late DoubleClickAnimationListener _doubleClickAnimationListener;
  late AnimationController _doubleClickAnimationController;
  List<double> doubleTapScales = <double>[1.0, 2.0];
  double fittedScale = 1.0;
  double initialScale = 1.0;
  int screenIndex=0;
  late PageController _pageController;
  GlobalKey<ExtendedImageSlidePageState> slidePagekey =
      GlobalKey<ExtendedImageSlidePageState>();

  void close() {
    Navigator.of(context).pop();
  }

  @override
  void initState() {
    super.initState();
    // 允许横屏
    screenIndex=widget.index!;
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.landscapeLeft,
      DeviceOrientation.landscapeRight,
      DeviceOrientation.portraitUp,
      DeviceOrientation.portraitDown,
    ]);
    _doubleClickAnimationController = AnimationController(
        duration: const Duration(milliseconds: 150), vsync: this);
    _pageController = PageController(initialPage: widget.index ?? 0);
  }

  @override
  void dispose() {
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitUp,
    ]);
    _doubleClickAnimationController.dispose();
    clearGestureDetailsCache();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return OrientationBuilder(builder: ((context, orientation) {
      return Container(
          color: Colors.transparent,
          constraints: BoxConstraints.expand(
            height: MediaQuery.of(context).size.height,
          ),
          child: Stack(
              alignment: Alignment.center,
              children: [
            ExtendedImageSlidePage(
              key: slidePagekey,
              slidePageBackgroundHandler: (Offset offset, Size size) {
                if (orientation == Orientation.landscape) {
                  return Colors.black;
                }
                double opacity = 0.0;
                opacity = offset.distance /
                    (Offset(size.width, size.height).distance / 2.0);
                return Colors.black
                    .withOpacity(min(1.0, max(1.0 - opacity, 0.0)));
              },
              slideType: SlideType.onlyImage,
              child: GestureDetector(
                  onTap: close,
                  child: ExtendedImageSlidePageHandler(
                    child: Stack(
                      children: <Widget>[
                        Positioned(
                            top: 0,
                            left: 0,
                            bottom: 0,
                            right: 0,
                            child: ExtendedImageGesturePageView.builder(
                              onPageChanged: (index){
                                setState(() {
                                  screenIndex=index;
                                  print('${index}**********');
                                });
                              },
                                controller: ExtendedPageController(
                                  initialPage: widget.index!,
                                  pageSpacing: 0,
                                  shouldIgnorePointerWhenScrolling: false,
                                ),
                                itemCount: widget.mData?.length,
                                itemBuilder: (context, index) {
                                  return ExtendedImage(
                                    image: NetworkImage(ConfigUtil.oss_url +
                                        widget.mData![index]),
                                    enableSlideOutPage: true,
                                    fit: BoxFit.contain,
                                    initGestureConfigHandler: (state) {
                                      return GestureConfig(
                                        minScale: 0.8,
                                        animationMinScale: 0.6,
                                        maxScale: 2 * fittedScale,
                                        animationMaxScale: 2.5 * fittedScale,
                                        speed: 1.0,
                                        inertialSpeed: 100.0,
                                        initialScale: initialScale,
                                        inPageView: true,
                                        initialAlignment:
                                            InitialAlignment.topCenter,
                                      );
                                    },
                                    loadStateChanged:
                                        (ExtendedImageState state) {
                                      switch (state.extendedImageLoadState) {
                                        case LoadState.loading:
                                          return Container(
                                              color: Colors.black,
                                              child: const Center(
                                                  child:
                                                      CircularProgressIndicator(
                                                          color:
                                                              Colors.white)));
                                        case LoadState.completed:
                                          final screenHeight =
                                              MediaQuery.of(context)
                                                  .size
                                                  .height;
                                          final screenWidth =
                                              MediaQuery.of(context).size.width;
                                          final imgHeight = state
                                                  .extendedImageInfo
                                                  ?.image
                                                  .height ??
                                              1;
                                          final imgWidth = state
                                                  .extendedImageInfo
                                                  ?.image
                                                  .width ??
                                              0;
                                          final imgRatio = imgWidth / imgHeight;
                                          final screenRatio =
                                              screenWidth / screenHeight;
                                          final fitWidthScale =
                                              screenRatio / imgRatio;
                                          if (screenRatio > imgRatio) {
                                            // Long Image
                                            initialScale = fitWidthScale;
                                            fittedScale = fitWidthScale;
                                            doubleTapScales[1] = fitWidthScale;
                                          } else {
                                            fittedScale = 1 /
                                                fitWidthScale; // fittedHeight
                                            doubleTapScales[1] =
                                                1 / fitWidthScale;
                                          }
                                          break;
                                        case LoadState.failed:
                                          break;
                                      }
                                      return null;
                                    },
                                    onDoubleTap:
                                        (ExtendedImageGestureState state) {
                                      ///you can use define pointerDownPosition as you can,
                                      ///default value is double tap pointer down postion.
                                      final Offset? pointerDownPosition =
                                          state.pointerDownPosition;
                                      final double? begin =
                                          state.gestureDetails!.totalScale;
                                      double end;

                                      //remove old
                                      _doubleClickAnimation?.removeListener(
                                          _doubleClickAnimationListener);

                                      //stop pre
                                      _doubleClickAnimationController.stop();

                                      //reset to use
                                      _doubleClickAnimationController.reset();

                                      if (begin == doubleTapScales[0]) {
                                        end = doubleTapScales[1];
                                      } else {
                                        end = doubleTapScales[0];
                                      }

                                      _doubleClickAnimationListener = () {
                                        //print(_animation.value);
                                        state.handleDoubleTap(
                                            scale: _doubleClickAnimation!.value,
                                            doubleTapPosition:
                                                pointerDownPosition);
                                      };
                                      _doubleClickAnimation =
                                          _doubleClickAnimationController.drive(
                                              Tween<double>(
                                                  begin: begin, end: end));

                                      _doubleClickAnimation!.addListener(
                                          _doubleClickAnimationListener);

                                      _doubleClickAnimationController.forward();
                                    },
                                    mode: ExtendedImageMode.gesture,
                                  );

                                })),
                      ],
                    ),
                    heroBuilderForSlidingPage: (Widget result) {
                      return Hero(
                        tag: widget.heroTag,
                        child: result,
                        flightShuttleBuilder: (BuildContext flightContext,
                            Animation<double> animation,
                            HeroFlightDirection flightDirection,
                            BuildContext fromHeroContext,
                            BuildContext toHeroContext) {
                          final Hero hero =
                              (flightDirection == HeroFlightDirection.pop
                                  ? fromHeroContext.widget
                                  : toHeroContext.widget) as Hero;

                          return hero.child;
                        },
                      );
                    },
                  )),
            ),
            Positioned(
                left: 10,
                bottom: 50,
                child: IconButton(
                  icon: Image.asset(
                    'images/close.png',
                    package: 'tim_ui_kit',
                  ),
                  iconSize: 30,
                  onPressed: close,
                )),
            Positioned(
                bottom: 62,
                child: Container(
                  padding: EdgeInsets.symmetric(horizontal: 8),
                  height: 20,
                  decoration: BoxDecoration(
                    color: Colors.white38,
                    borderRadius: BorderRadius.all(Radius.circular(8))
                  ),
                  child: Center(
                    child: Text('${screenIndex+1}/${widget.mData?.length.toInt()}',style: TextStyle(fontSize: 14,color: Colors.white),),
                  ),
                )
            ),
            Positioned(
              right: 10,
              bottom: 50,
              child: IconButton(
                icon: Image.asset(
                  'images/download.png',
                  package: 'tim_ui_kit',
                ),
                iconSize: 30,
                onPressed: (){
                  widget.downloadFn.call((screenIndex));
                  print('${screenIndex}+++++++++++++++');
                },
              ),
            )
          ]));
    }));
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值