当前位置: 首页 > news >正文

哪个网站做调查赚钱多电商seo是什么意思

哪个网站做调查赚钱多,电商seo是什么意思,网站ico设计,wordpress+商场源码flutter开发实战-hero实现图片预览功能extend_image 在开发中#xff0c;经常遇到需要图片预览#xff0c;当feed中点击一个图片#xff0c;开启预览#xff0c;多个图片可以左右切换swiper#xff0c;双击图片及手势进行缩放功能。 这个主要实现使用extend_image插件。在…flutter开发实战-hero实现图片预览功能extend_image 在开发中经常遇到需要图片预览当feed中点击一个图片开启预览多个图片可以左右切换swiper双击图片及手势进行缩放功能。 这个主要实现使用extend_image插件。在点击图片时候使用hero动画进行展示。 Hero简单使用可以查看https://brucegwo.blog.csdn.net/article/details/134005601 hero实现图片预览功能效果图 一、图片GridView 在展示多张图片使用GridView来展示。 GridView可以构建一个二维网格列表其默认构造函数定义如下 GridView({Key? key,Axis scrollDirection Axis.vertical,bool reverse false,ScrollController? controller,bool? primary,ScrollPhysics? physics,bool shrinkWrap false,EdgeInsetsGeometry? padding,required this.gridDelegate, //下面解释bool addAutomaticKeepAlives true,bool addRepaintBoundaries true,double? cacheExtent, ListWidget children const Widget[],...})SliverGridDelegate是一个抽象类定义了GridView Layout相关接口子类需要通过实现它们来实现具体的布局算法。 实现展示图片GridView GridView.builder(gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(maxCrossAxisExtent: 300,crossAxisSpacing: 10,mainAxisSpacing: 10,),itemBuilder: (BuildContext context, int index) {...完整代码如下 class GridSimplePhotoViewDemo extends StatefulWidget {override_GridSimplePhotoViewDemoState createState() _GridSimplePhotoViewDemoState(); }class _GridSimplePhotoViewDemoState extends StateGridSimplePhotoViewDemo {ListString images 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,This is an video,https://photo.tuchong.com/5040418/f/43305517.jpg,https://photo.tuchong.com/3019649/f/302699092.jpg];overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text(SimplePhotoView),),body: Padding(padding: const EdgeInsets.all(10.0),child: GridView.builder(gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(maxCrossAxisExtent: 300,crossAxisSpacing: 10,mainAxisSpacing: 10,),itemBuilder: (BuildContext context, int index) {final String url images[index];return GestureDetector(child: AspectRatio(aspectRatio: 1.0,child: Hero(tag: url,child: url This is an video? Container(alignment: Alignment.center,child: const Text(This is an video),): ExtendedImage.network(url,fit: BoxFit.cover,),),),onTap: () {Navigator.of(context).push(TransparentPageRoute(pageBuilder:(BuildContext context, Animationdouble animation,Animationdouble secondaryAnimation) {return PicSwiper(index: index,pics: images,);}));},);},itemCount: images.length,),),);} }二、跳转到Swiper的TransparentPageRoute 当点击跳转到新的页面的时候可以使用TransparentPageRoute该类继承与PageRouteBuilder实现FadeTransition在点击图片展示预览图片的时候通过渐隐渐显的方式跳转到下一个路由。 Widget _defaultTransitionsBuilder(BuildContext context,Animationdouble animation,Animationdouble secondaryAnimation,Widget child,) {return FadeTransition(opacity: CurvedAnimation(parent: animation,curve: Curves.easeOut,),child: child,); }完整代码如下 import package:flutter/material.dart;/// Transparent Page Route class TransparentPageRouteT extends PageRouteBuilderT {TransparentPageRoute({RouteSettings? settings,required RoutePageBuilder pageBuilder,RouteTransitionsBuilder transitionsBuilder _defaultTransitionsBuilder,Duration transitionDuration const Duration(milliseconds: 250),bool barrierDismissible false,Color? barrierColor,String? barrierLabel,bool maintainState true,}) : super(settings: settings,opaque: false,pageBuilder: pageBuilder,transitionsBuilder: transitionsBuilder,transitionDuration: transitionDuration,barrierDismissible: barrierDismissible,barrierColor: barrierColor,barrierLabel: barrierLabel,maintainState: maintainState,); }Widget _defaultTransitionsBuilder(BuildContext context,Animationdouble animation,Animationdouble secondaryAnimation,Widget child,) {return FadeTransition(opacity: CurvedAnimation(parent: animation,curve: Curves.easeOut,),child: child,); }三、使用extend_image 在pubspec.yaml引入extend_image # extended_imageextended_image: ^7.0.2当点击图片的时候传入多张图片定位到当前的index多个图片可以左右切换Swiper。这里使用到了ExtendedImageGesturePageView。ExtendedImageGesturePageView与PageView类似它是为显示缩放/平移图像而设计的。 如果您已经缓存了手势请记住在正确的时间调用clearGestureDetailsCache方法。例如页面视图页面被丢弃 ExtendedImageGesturePageView属性 cacheGesture 保存手势状态例如在ExtendedImageGesturePageView中向后滚动时手势状态不会改变记住clearGestureDetailsCacheinPageView 是否在ExtendedImageGesturePageView中 使用示例 ExtendedImageGesturePageView.builder(itemBuilder: (BuildContext context, int index) {var item widget.pics[index].picUrl;Widget image ExtendedImage.network(item,fit: BoxFit.contain,mode: ExtendedImageMode.gesture,gestureConfig: GestureConfig(inPageView: true, initialScale: 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: false),);image Container(child: image,padding: EdgeInsets.all(5.0),);if (index currentIndex) {return Hero(tag: item index.toString(),child: image,);} else {return image;}},itemCount: widget.pics.length,onPageChanged: (int index) {currentIndex index;rebuild.add(index);},controller: PageController(initialPage: currentIndex,),scrollDirection: Axis.horizontal, )四、使用hero_widget 当点击图片实现hero_widget实现hero动画来实现图片预览。 使用Flutter的Hero widget创建hero动画。 将hero从一个路由飞到另一个路由。 将hero 的形状从圆形转换为矩形,同时将其从一个路由飞到另一个路由的过程中进行动画处理。 这里使用的hero_widget完整代码如下 import package:extended_image/extended_image.dart; import package:flutter/material.dart;/// make hero better when slide out class HeroWidget extends StatefulWidget {const HeroWidget({required this.child,required this.tag,required this.slidePagekey,this.slideType SlideType.onlyImage,});final Widget child;final SlideType slideType;final Object tag;final GlobalKeyExtendedImageSlidePageState slidePagekey;override_HeroWidgetState createState() _HeroWidgetState(); }class _HeroWidgetState extends StateHeroWidget {RectTween? _rectTween;overrideWidget build(BuildContext context) {return Hero(tag: widget.tag,createRectTween: (Rect? begin, Rect? end) {_rectTween RectTween(begin: begin, end: end);return _rectTween!;},// make hero better when slide outflightShuttleBuilder: (BuildContext flightContext,Animationdouble animation,HeroFlightDirection flightDirection,BuildContext fromHeroContext,BuildContext toHeroContext) {// make hero more smoothlyfinal Hero hero (flightDirection HeroFlightDirection.pop? fromHeroContext.widget: toHeroContext.widget) as Hero;if (_rectTween null) {return hero;}if (flightDirection HeroFlightDirection.pop) {final bool fixTransform widget.slideType SlideType.onlyImage (widget.slidePagekey.currentState!.offset ! Offset.zero ||widget.slidePagekey.currentState!.scale ! 1.0);final Widget toHeroWidget (toHeroContext.widget as Hero).child;return AnimatedBuilder(animation: animation,builder: (BuildContext buildContext, Widget? child) {Widget animatedBuilderChild hero.child;// make hero more smoothlyanimatedBuilderChild Stack(clipBehavior: Clip.antiAlias,alignment: Alignment.center,children: Widget[Opacity(opacity: 1 - animation.value,child: UnconstrainedBox(child: SizedBox(width: _rectTween!.begin!.width,height: _rectTween!.begin!.height,child: toHeroWidget,),),),Opacity(opacity: animation.value,child: animatedBuilderChild,)],);// fix transform when slide outif (fixTransform) {final TweenOffset offsetTween TweenOffset(begin: Offset.zero,end: widget.slidePagekey.currentState!.offset);final Tweendouble scaleTween Tweendouble(begin: 1.0, end: widget.slidePagekey.currentState!.scale);animatedBuilderChild Transform.translate(offset: offsetTween.evaluate(animation),child: Transform.scale(scale: scaleTween.evaluate(animation),child: animatedBuilderChild,),);}return animatedBuilderChild;},);}return hero.child;},child: widget.child,);} }五、使用Pic_Swiper 在swiper左右切换功能使用ExtendedImageGesturePageView来实现切换功能双击图片及手势进行缩放功能。 完整代码如下 typedef DoubleClickAnimationListener void Function();class PicSwiper extends StatefulWidget {const PicSwiper({super.key,this.index,this.pics,});final int? index;final ListString? pics;override_PicSwiperState createState() _PicSwiperState(); }class _PicSwiperState extends StatePicSwiper with TickerProviderStateMixin {final StreamControllerint rebuildIndex StreamControllerint.broadcast();final StreamControllerbool rebuildSwiper StreamControllerbool.broadcast();final StreamControllerdouble rebuildDetail StreamControllerdouble.broadcast();late AnimationController _doubleClickAnimationController;late AnimationController _slideEndAnimationController;late Animationdouble _slideEndAnimation;Animationdouble? _doubleClickAnimation;late DoubleClickAnimationListener _doubleClickAnimationListener;Listdouble doubleTapScales double[1.0, 2.0];GlobalKeyExtendedImageSlidePageState slidePagekey GlobalKeyExtendedImageSlidePageState();int? _currentIndex 0;bool _showSwiper true;double _imageDetailY 0;Rect? imageDRect;overrideWidget build(BuildContext context) {final Size size MediaQuery.of(context).size;double statusBarHeight MediaQuery.of(context).padding.top;imageDRect Offset.zero size;Widget result Material(color: Colors.transparent,shadowColor: Colors.transparent,child: Stack(fit: StackFit.expand,children: Widget[ExtendedImageGesturePageView.builder(controller: ExtendedPageController(initialPage: widget.index!,pageSpacing: 50,shouldIgnorePointerWhenScrolling: false,),scrollDirection: Axis.horizontal,physics: const BouncingScrollPhysics(),canScrollPage: (GestureDetails? gestureDetails) {return _imageDetailY 0;},itemBuilder: (BuildContext context, int index) {final String item widget.pics![index];Widget image ExtendedImage.network(item,fit: BoxFit.contain,enableSlideOutPage: true,mode: ExtendedImageMode.gesture,imageCacheName: CropImage,//layoutInsets: EdgeInsets.all(20),initGestureConfigHandler: (ExtendedImageState state) {double? initialScale 1.0;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!,maxScale: max(initialScale, 5.0),animationMaxScale: max(initialScale, 5.0),initialAlignment: InitialAlignment.center,//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: false,);},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(Tweendouble(begin: begin, end: end));_doubleClickAnimation!.addListener(_doubleClickAnimationListener);_doubleClickAnimationController.forward();},loadStateChanged: (ExtendedImageState state) {if (state.extendedImageLoadState LoadState.completed) {return StreamBuilderdouble(builder:(BuildContext context, AsyncSnapshotdouble data) {return ExtendedImageGesture(state,imageBuilder: (Widget image) {return Stack(children: Widget[Positioned.fill(child: image,),],);},);},initialData: _imageDetailY,stream: rebuildDetail.stream,);}return null;},);image HeroWidget(tag: item,slideType: SlideType.onlyImage,slidePagekey: slidePagekey,child: image,);image GestureDetector(child: image,onTap: () {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);},),StreamBuilderbool(builder: (BuildContext c, AsyncSnapshotbool d) {if (d.data null || !d.data!) {return Container();}return Positioned(top: statusBarHeight,left: 0.0,right: 0.0,child: MySwiperPlugin(widget.pics, _currentIndex, rebuildIndex),);},initialData: true,stream: rebuildSwiper.stream,)],),);result ExtendedImageSlidePage(key: slidePagekey,child: result,slideAxis: SlideAxis.vertical,slideType: SlideType.onlyImage,slideScaleHandler: (Offset offset, {ExtendedImageSlidePageState? state,}) {return null;},slideOffsetHandler: (Offset offset, {ExtendedImageSlidePageState? state,}) {return null;},slideEndHandler: (Offset offset, {ExtendedImageSlidePageState? state,ScaleEndDetails? details,}) {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);}},);return result;}overridevoid dispose() {rebuildIndex.close();rebuildSwiper.close();rebuildDetail.close();_doubleClickAnimationController.dispose();_slideEndAnimationController.dispose();clearGestureDetailsCache();//cancelToken?.cancel();super.dispose();}overridevoid initState() {super.initState();_currentIndex widget.index;_doubleClickAnimationController AnimationController(duration: const Duration(milliseconds: 150), vsync: this);_slideEndAnimationController AnimationController(vsync: this,duration: const Duration(milliseconds: 150),);_slideEndAnimationController.addListener(() {_imageDetailY _slideEndAnimation.value;if (_imageDetailY 0) {_showSwiper true;rebuildSwiper.add(_showSwiper);}rebuildDetail.sink.add(_imageDetailY);});} }class MySwiperPlugin extends StatelessWidget {const MySwiperPlugin(this.pics, this.index, this.reBuild);final ListString? pics;final int? index;final StreamControllerint reBuild;overrideWidget build(BuildContext context) {return StreamBuilderint(builder: (BuildContext context, AsyncSnapshotint data) {return DefaultTextStyle(style: const TextStyle(color: Colors.blue),child: Container(height: 50.0,width: double.infinity,// color: Colors.grey.withOpacity(0.2),child: Row(children: Widget[Container(width: 10.0,),Text(${data.data! 1},),Text( / ${pics!.length},),const SizedBox(width: 10.0,),const SizedBox(width: 10.0,),if (!kIsWeb)GestureDetector(child: Container(padding: const EdgeInsets.only(right: 10.0),alignment: Alignment.center,child: const Text(Save,style: TextStyle(fontSize: 16.0, color: Colors.blue),),),onTap: () {// saveNetworkImageToPhoto(pics![index!].picUrl)// .then((bool done) {// showToast(done ? save succeed : save failed,// position: const ToastPosition(// align: Alignment.topCenter));// });},),],),),);},initialData: index,stream: reBuild.stream,);} }class ImageDetailInfo {ImageDetailInfo({required this.imageDRect,required this.pageSize,required this.imageInfo,});final GlobalKeyStateStatefulWidget key GlobalKeyState();final Rect imageDRect;final Size pageSize;final ImageInfo imageInfo;double? _maxImageDetailY;double get imageBottom imageDRect.bottom - 20;double get maxImageDetailY {try {//return _maxImageDetailY ?? max(key.currentContext!.size!.height - (pageSize.height - imageBottom),0.1);} catch (e) {//currentContext is not readyreturn 100.0;}} }使用过程中的util import package:extended_image/extended_image.dart; import package:flutter/foundation.dart; import package:flutter/rendering.dart;/// /// create by zmtzawqlp on 2020/1/31 /// double? initScale({required Size imageSize,required Size size,double? initialScale, }) {final double n1 imageSize.height / imageSize.width;final double n2 size.height / size.width;if (n1 n2) {final FittedSizes fittedSizes applyBoxFit(BoxFit.contain, imageSize, size);//final Size sourceSize fittedSizes.source;final Size destinationSize fittedSizes.destination;return size.width / destinationSize.width;} else if (n1 / n2 1 / 4) {final FittedSizes fittedSizes applyBoxFit(BoxFit.contain, imageSize, size);//final Size sourceSize fittedSizes.source;final Size destinationSize fittedSizes.destination;return size.height / destinationSize.height;}return initialScale; }效果视频 六、小结 flutter开发实战-hero实现图片预览功能extend_image。描述可能不太准确请见谅。 学习记录每天不停进步。
http://www.yutouwan.com/news/340335/

相关文章:

  • 唐山网站开发寻找移动网站建设
  • .net网站空间山西网站建设哪家好
  • 四川省住建厅官网湘潭优化公司
  • vs做网站怎样添加图片北京市推广公司
  • 长沙建网站的公司一对一定制方案制作微信公众的网站开发
  • 优化门户网站建设网站建设平台硬件要求
  • 广州海珠区最新通告柳市网站优化
  • 成都大型网站建设公司购物网站建设模板
  • 云网站后台招聘网站页面设计图片
  • 在建立网站站点的过程中wordpress安装插件失败
  • 宁波制作网站哪个好光泽网站建设
  • 网站建设600元全包佛山市企业网站建设报价
  • 网站项目意义网站开发 业务流程图
  • 怎么给网站做支付接口昆明网站设计公司哪家好
  • 手机站电影如何制作一个自己的网站?
  • 网页主要由三部分组成宁波关键词优化企业网站建设
  • 企业微信平台株洲关键词seo优化服务商
  • 地产网站建设方案网页制作接单
  • 广州网站开发系统丽水开发区建设局网站廉租房
  • 外贸网站高端定做怎么制作软件程序
  • 成都建设网站公司简介教人做衣服得网站有哪些
  • 百度网站官网app定制排名
  • 域名打不开原来的网站wordpress两个站点
  • 网站开发技术汇总建宣传网站
  • 不要验证码的广告网站怎么创建网站充值和提现账号
  • 建设银行手机短信网站怎么开通百度网络营销中心
  • vs 2015可以做网站吗wordpress外链批量保存本地
  • 阜阳微商城网站建设电子商务网站建设的开发背景
  • 通过ip直连打开网站要怎么做网站建设设计文档模板
  • excel表如何做网站连接常熟沿江开发区人才网