We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8.2.0
Android, iOS
小米9
Flutter version 2.5.1
我是ExtendedImageSlidePage中嵌套ExtendedImageGesturePageView,实现的看大图的需求,就是我手往下滑动大图界面能关掉,没有问题。但是问题是:
`@override Widget build(BuildContext context) { final Size size = MediaQuery.of(context).size; imageDRect = Offset.zero & size;
Widget result = ExtendedImageSlidePage( key: slidePagekey, // slideAxis: SlideAxis.vertical, // slideType: SlideType.wholePage, //在滑动页面的时候根据 Offset 自定义整个页面的背景色 slidePageBackgroundHandler: ( Offset offset, Size pageSize, ) { double opacity = 0.0; // if (pageGestureAxis == SlideAxis.both) { opacity = offset.distance / (Offset(pageSize.width, pageSize.height).distance / 2.0); // } else if (pageGestureAxis == SlideAxis.horizontal) { // opacity = offset.dx.abs() / (pageSize.width / 2.0); // } else if (pageGestureAxis == SlideAxis.vertical) { // opacity = offset.dy.abs() / (pageSize.height / 2.0); // } return const Color(0x00000000) .withOpacity(min(1.0, max(1.0 - opacity, 0.0))); }, //在滑动页面的时候根据 Offset 自定义整个页面的缩放值 slideScaleHandler: ( Offset offset, { ExtendedImageSlidePageState? state, }) { //image is ready and it's not sliding. if (state != null && detailKeys[_currentIndex!] != null && state.scale == 1.0) { //don't slide page if scale of image is more than 1.0 if (state.imageGestureState!.gestureDetails!.totalScale! > 1.0) { return 1.0; } //or slide down into detail mode if (offset.dy < 0 || _imageDetailY < 0) { return 1.0; } } return null; }, //在滑动页面的时候自定义 Offset slideOffsetHandler: ( Offset offset, { ExtendedImageSlidePageState? state, }) { //image is ready and it's not sliding. if (state != null && detailKeys[_currentIndex!] != null && state.scale == 1.0) { //don't slide page if scale of image is more than 1.0 if (state.imageGestureState!.gestureDetails!.totalScale! > 1.0) { return Offset.zero; } //or slide down into detail mode if (offset.dy < 0 || _imageDetailY < 0) { _imageDetailY += offset.dy; // print(offset.dy); _imageDetailY = max( -detailKeys[_currentIndex!]!.maxImageDetailY, _imageDetailY); rebuildDetail.sink.add(_imageDetailY); return Offset.zero; } if (_imageDetailY != 0) { _imageDetailY = 0; _showSwiper = true; rebuildSwiper.add(_showSwiper); rebuildDetail.sink.add(_imageDetailY); } } return null; }, //滑动页面结束的时候计算是否需要 pop 页面 slideEndHandler: ( Offset offset, { ExtendedImageSlidePageState? state, ScaleEndDetails? details, }) { if (_imageDetailY != 0 && state!.scale == 1) { if (!_slideEndAnimationController.isAnimating) {
// get magnitude from gesture velocity final double magnitude = details!.velocity.pixelsPerSecond.distance;
// do a significant magnitude if (magnitude.greaterThanOrEqualTo(minMagnitude)) { final Offset direction = details.velocity.pixelsPerSecond / magnitude * 1000; _slideEndAnimation = _slideEndAnimationController.drive(Tween<double>( begin: _imageDetailY, end: (_imageDetailY + direction.dy) .clamp(-detailKeys[_currentIndex!]!.maxImageDetailY, 0.0), )); _slideEndAnimationController.reset(); _slideEndAnimationController.forward(); } } return false; } return null; }, //滑动页面的回调,你可以在这里改变页面上其他元素的状态 onSlidingPage: (ExtendedImageSlidePageState state) { ///you can change other widgets' state on page as you want ///base on offset/isSliding etc //var offset= state.offset; final bool showSwiper = !state.isSliding; if (showSwiper != _showSwiper) { // do not setState directly here, the image state will change, // you should only notify the widgets which are needed to change // setState(() { // _showSwiper = showSwiper; // }); _showSwiper = showSwiper; rebuildSwiper.add(_showSwiper); } }, child: Material( /// if you use ExtendedImageSlidePage and slideType =SlideType.onlyImage, /// make sure your page is transparent background color: Colors.transparent, // color: Colors.redAccent, shadowColor: Colors.transparent, child: Stack( fit: StackFit.expand, children: <Widget>[ ExtendedImageGesturePageView.builder( controller: ExtendedPageController( initialPage: widget.index!, // pageSpacing: 32,//两个图之间的边距 越大,在A图的右边就能看见B图 2024年5月31日11:18:28 shouldIgnorePointerWhenScrolling: true, ), scrollDirection: Axis.horizontal, // physics: const BouncingScrollPhysics(), //定义PageView的滚动行为 canScrollPage: (GestureDetails? gestureDetails) { return _imageDetailY >= 0; //return (gestureDetails?.totalScale ?? 1.0) <= 1.0; }, itemBuilder: (BuildContext context, int index) { int imageTyep = widget.pics![index].type; late Widget image; Map extendParams = { "fit": BoxFit.contain, "enableSlideOutPage": true, "mode": ExtendedImageMode.gesture, // 手势配置的回调(图片加载完成时).你可以根据图片的信息比如宽高,来初始化 "initGestureConfigHandler": (ExtendedImageState state) { double? initialScale = 1.0; //暂时不要这个了 直接初始默认就是1 而不要计算的,因为对于大图会出现一开始是方法的模式 2024年5月31日10:26:11 if (state.extendedImageInfo != null) { initialScale = initScale( size: size, initialScale: initialScale, imageSize: Size( state.extendedImageInfo!.image.width.toDouble(), state.extendedImageInfo!.image.height .toDouble())); } return GestureConfig( inPageView: true, // initialScale: initialScale!, initialScale: 1, // maxScale: max(initialScale, 5.0), // animationMaxScale: max(initialScale, 5.0), initialAlignment: InitialAlignment.center, minScale: 1.0, //you can cache gesture state even though page view page change. //remember call clearGestureDetailsCache() method at the right time.(for example,this page dispose) cacheGesture: true, ); }, "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(); }, }; if (imageTyep == 0 || imageTyep == 60) { //网络图 final String? originPath = widget.pics![index].originPath; String? demoPath = widget.pics![index].demoPath; String? prePath = widget.pics![index].preViewDemo; String item; if (imageTyep == 60) { item = prePath ?? demoPath!; } else { item = originPath!; } image = createNetworkImage( item, index, extendParams: extendParams, // fit: BoxFit.contain, // enableSlideOutPage: true, // mode: ExtendedImageMode.gesture, loadStateChanged: (ExtendedImageState state) { if (state.extendedImageLoadState == LoadState.completed) { final Rect imageDRect = getDestinationRect( rect: Offset.zero & size, inputSize: Size( state.extendedImageInfo!.image.width.toDouble(), state.extendedImageInfo!.image.height.toDouble(), ), fit: BoxFit.contain, ); detailKeys[index] ??= ImageDetailInfo( imageDRect: imageDRect, pageSize: size, imageInfo: state.extendedImageInfo!, ); final ImageDetailInfo? imageDetailInfo = detailKeys[index]; return StreamBuilder<double>( builder: (BuildContext context, AsyncSnapshot<double> data) { return ExtendedImageGesture( state, canScaleImage: (_) => _imageDetailY == 0, imageBuilder: (Widget image) { return Stack( children: <Widget>[ Positioned.fill( top: _imageDetailY, bottom: -_imageDetailY, child: image, ), Positioned( left: 0.0, right: 0.0, top: imageDetailInfo!.imageBottom + _imageDetailY, child: Opacity( opacity: _imageDetailY == 0 ? 0 : min( 1, _imageDetailY.abs() / (imageDetailInfo .maxImageDetailY / 4.0), ), ), ), ], ); }, ); }, initialData: _imageDetailY, stream: rebuildDetail.stream, ); } else if (state.extendedImageLoadState == LoadState.loading) { return Center( child: Image.asset( "assets/images/loading.gif", width: 40, height: 40, ), ); } else if (state.extendedImageLoadState == LoadState.failed) { return GestureDetector( child: /*Container( color: const Color(0xFFF3F4F5), child:*/ Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Image.asset( "assets/images/img_load_failed.png", // "assets/images/loading.gif", width: 40, height: 40, ), const Padding( padding: EdgeInsets.only( left: 3, top: 15, right: 3), child: Text( "加载失败,点击重试", style: TextStyle( fontSize: 15, color: Color(0XFF999999)), textAlign: TextAlign.center, ), ) ]), // ), onTap: () { state.reLoadImage(); }, ); } return null; }, ); } else if (imageTyep == 1 || imageTyep == 61) { image = createFileWithWechatPicker( widget.pics![index].entity!, extendParams: extendParams, ); // tag = widget.pics![index].tag; } if (index < min(9, widget.pics!.length)) { image = HeroWidget( tag: widget.pics![index].tag, slideType: SlideType.onlyImage, slidePagekey: slidePagekey, child: image, ); } image = GestureDetector( child: image, onTap: () { if (_imageDetailY != 0) { _imageDetailY = 0; rebuildDetail.sink.add(_imageDetailY); } else { slidePagekey.currentState!.popPage(); Navigator.pop(context); } }, ); return image; }, itemCount: widget.pics!.length, onPageChanged: (int index) { _currentIndex = index; rebuildIndex.add(index); if (_imageDetailY != 0) { _imageDetailY = 0; rebuildDetail.sink.add(_imageDetailY); } _showSwiper = true; rebuildSwiper.add(_showSwiper); _preloadImage(index - 1); _preloadImage(index + 1); }, ), Visibility( visible: !(widget.isOnlyPreview && widget.pics!.length == 1), child: StreamBuilder<bool>( //负责根据不同状态创建对应ui的方法实现 builder: (BuildContext c, AsyncSnapshot<bool> d) { if (d.data == null || !d.data!) { return Container(); } return Positioned( bottom: 0.0, left: 0.0, right: 0.0, child: MySwiperPlugin(widget.pics, _currentIndex, rebuildIndex, widget.operateMenu), ); }, initialData: true, //默认初始化数据 stream: rebuildSwiper .stream, //stream事件流对象 rebuildSwiper.stream获取Stream用作事件监听 )) ], ), )); return result;
}`
No response
[email protected]
The text was updated successfully, but these errors were encountered:
No branches or pull requests
Version
8.2.0
Platforms
Android, iOS
Device Model
小米9
flutter info
How to reproduce?
我是ExtendedImageSlidePage中嵌套ExtendedImageGesturePageView,实现的看大图的需求,就是我手往下滑动大图界面能关掉,没有问题。但是问题是:
`@override
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
imageDRect = Offset.zero & size;
// get magnitude from gesture velocity
final double magnitude =
details!.velocity.pixelsPerSecond.distance;
}`
Logs
No response
Example code (optional)
No response
Contact
[email protected]
The text was updated successfully, but these errors were encountered: