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

网站js下载网络营销未来有哪些发展趋势

网站js下载,网络营销未来有哪些发展趋势,南庄顺德网站建设,wordpress coreflutter开发实战-手势Gesture与ListView滚动竞技场的可滑动关闭组件 最近看到了一个插件#xff0c;实现一个可滑动关闭组件。滑动关闭组件即手指向下滑动#xff0c;组件随手指移动#xff0c;当移动一定位置时候#xff0c;手指抬起后组件滑出屏幕。 一、GestureDetect…flutter开发实战-手势Gesture与ListView滚动竞技场的可滑动关闭组件 最近看到了一个插件实现一个可滑动关闭组件。滑动关闭组件即手指向下滑动组件随手指移动当移动一定位置时候手指抬起后组件滑出屏幕。 一、GestureDetector嵌套Container非ListView 如果要可滑动关闭则需要手势GestureDetectorGestureDetector这里实现了onVerticalDragDown、onVerticalDragUpdate、onVerticalDragEnd通过手势更新AnimatedContainer的高度。 overrideWidget build(BuildContext context) {Size screenSize MediaQuery.of(context).size;return Column(mainAxisSize: MainAxisSize.min,children: Widget[GestureDetector(onVerticalDragDown: _onVerticalDragDown,onVerticalDragUpdate: _onVerticalDragUpdate,onVerticalDragEnd: _onVerticalDragEnd,child: AnimatedContainer(curve: Curves.easeOut,duration: Duration(milliseconds: 250),onEnd: () {_onAniPositionedEnd(context);},height: yBottomOffset widget.displayHeight,width: screenSize.width,clipBehavior: Clip.hardEdge,decoration: const BoxDecoration(color: Colors.transparent,),child: widget.child,),),],);} 我们通过onVerticalDragUpdate来更新AnimatedContainer的高度height void _onVerticalDragUpdate(DragUpdateDetails details) {print(_onVerticalDragUpdate);if (details.delta.dy 0) {// 向上isDragDirectionUp true;} else {// 向下isDragDirectionUp false;}yBottomOffset - details.delta.dy;if (yBottomOffset 0.0) {yBottomOffset 0.0;}if (yBottomOffset -widget.displayHeight) {yBottomOffset -widget.displayHeight;}setState(() {});} 当拖动手势结束之后来检测是否是隐藏状态。 void _onVerticalDragEnd(DragEndDetails details) {print(_onVerticalDragEnd);if (yBottomOffset -widget.displayHeight / 3) {// 隐藏移除yBottomOffset -widget.displayHeight;isCompleteHide true;} else {yBottomOffset 0.0;isCompleteHide false;}setState(() {});} AnimatedContainer中有onEnd方法回调当动画结束之后在此方法回调中来处理是否pop等操作 void _onAniPositionedEnd(BuildContext context) {print(_onAniPositionedEnd);if (isCompleteHide) {// 隐藏了则移除Navigator.of(context).pop();}} DragBottomSheet2完整代码如下 import package:flutter/material.dart;class DragBottomSheet2 extends StatefulWidget {const DragBottomSheet2({super.key,required this.child,required this.displayHeight,});// childfinal Widget child;// 展示的child高度final double displayHeight;overrideStateDragBottomSheet2 createState() _DragBottomSheet2State(); }class _DragBottomSheet2State extends StateDragBottomSheet2 {bool? isDragDirectionUp;double yBottomOffset 0.0;bool isCompleteHide false;void _onVerticalDragDown(DragDownDetails details) {print(_onVerticalDragDown);}void _onVerticalDragUpdate(DragUpdateDetails details) {print(_onVerticalDragUpdate);if (details.delta.dy 0) {// 向上isDragDirectionUp true;} else {// 向下isDragDirectionUp false;}yBottomOffset - details.delta.dy;if (yBottomOffset 0.0) {yBottomOffset 0.0;}if (yBottomOffset -widget.displayHeight) {yBottomOffset -widget.displayHeight;}setState(() {});}void _onVerticalDragEnd(DragEndDetails details) {print(_onVerticalDragEnd);if (yBottomOffset -widget.displayHeight / 3) {// 隐藏移除yBottomOffset -widget.displayHeight;isCompleteHide true;} else {yBottomOffset 0.0;isCompleteHide false;}setState(() {});}void _onAniPositionedEnd(BuildContext context) {print(_onAniPositionedEnd);if (isCompleteHide) {// 隐藏了则移除Navigator.of(context).pop();}}overrideWidget build(BuildContext context) {Size screenSize MediaQuery.of(context).size;return Column(mainAxisSize: MainAxisSize.min,children: Widget[GestureDetector(onVerticalDragDown: _onVerticalDragDown,onVerticalDragUpdate: _onVerticalDragUpdate,onVerticalDragEnd: _onVerticalDragEnd,child: AnimatedContainer(curve: Curves.easeOut,duration: Duration(milliseconds: 250),onEnd: () {_onAniPositionedEnd(context);},height: yBottomOffset widget.displayHeight,width: screenSize.width,clipBehavior: Clip.hardEdge,decoration: const BoxDecoration(color: Colors.transparent,),child: widget.child,),),],);} } 点击按钮弹出bottomSheet2代码如下 void showBottomSheet2(BuildContext context) {Size size MediaQuery.of(context).size;double displayHeight size.height - 88;showModalBottomSheet(context: context,isScrollControlled: true,builder: (ctx) {return DragBottomSheet2(displayHeight: displayHeight,child: Container(width: size.width,height: displayHeight,color: Colors.orangeAccent,child: Text(内容,style: TextStyle(color: Colors.black,),),),);},);} 效果图如下 二、GestureDetector嵌套ListView GestureDetector嵌套ListView后Flutter会根据竞技场Arena机制通过一定逻辑选择一个组件胜出。 Flutter为了解决手势冲突问题Flutter给开发者提供了一套解决方案。在该方案中Flutter引入了Arena竞技场概念然后把冲突的手势加入到Arena中并竞争谁胜利谁就获得手势的后续处理权。 Arena竞技场的原理请看https://juejin.cn/post/6874570159768633357 所以在GestureDetector嵌套ListView后Flutter框架会将这些Gesture与ListView组件都加入竞技场然后通过一定的逻辑选择一个组件胜出通常同类组件嵌套时最内层的组件胜出胜出的组件会处理接下来的move和up事件其它组件则不会继续处理这些事件了。所以在GestureDetector嵌套ListView的场景中由于是ListView最终胜出所以后续的事件都交由ListView处理而GestureDetector收不到后续的事件也就不会响应用户的手势了。因此我们解决这个问题的第一步就是要让GestureDetector在这种场景下也能收到后续的事件 参考请看https://zhuanlan.zhihu.com/p/680586251 我们需要根据GestureDetector真正处理用户手势事件的是内部的Recognizer比如处理上下滑动的是VerticalDragGestureRecognizer而Recognizer在竞技场失败后也可以单方面宣布自己胜出这样即使在竞技场失败了GestureDetector也能收到后续的手势事件 因此我们现定义一个单方面宣布胜出的Recognizer class _MyVerticalDragGestureRecognizer extends VerticalDragGestureRecognizer {overridevoid rejectGesture(int pointer) {// 单方面宣布自己胜出acceptGesture(pointer);} } 我们需要将Recognizer加入到GestureDetector中会用到RawGestureDetector RawGestureDetector(gestures: {_MyVerticalDragGestureRecognizer: GestureRecognizerFactoryWithHandlers_MyVerticalDragGestureRecognizer(() _MyVerticalDragGestureRecognizer(),(_MyVerticalDragGestureRecognizer recognizer) {recognizer..onStart (DragStartDetails details) {}..onUpdate (DragUpdateDetails details) {}..onEnd (DragEndDetails details) {};}),},child: ...); 这时候当滚动ListView时候也能收到手势事件了。 监听ListView的滚动时候我们需要用到NotificationListener NotificationListener( // 监听内部ListView的滑动变化onNotification: (ScrollNotification notification) {if (notification is OverscrollNotification notification.overscroll 0) {// 用户向下滑动ListView已经滑动到顶部处理GestureDetector的滑动事件} else if (notification is ScrollUpdateNotification) {// 用户在ListView中执行滑动动作关闭外部GestureDetector的滑动处理} else {}return false;},child: //ListView), 最后DragGestureBottomSheet完整代码如下 import package:flutter/gestures.dart; import package:flutter/material.dart; import package:flutter_app_demolab/drag_sheet_controller.dart;class DragGestureBottomSheet extends StatefulWidget {const DragGestureBottomSheet({super.key,required this.child,required this.displayHeight,this.duration const Duration(milliseconds: 200),this.openDraggable true,this.autoNavigatorPop true,this.onShow,this.onHide,});// childfinal Widget child;// 展示的child高度final double displayHeight;// 拖动动画时长durationfinal Duration duration;// 是否需要拖动final bool openDraggable;// 是否需要自动popfinal bool autoNavigatorPop;// This method will be executed when the solid bottom sheet is completely// opened.final void Function()? onShow;// This method will be executed when the solid bottom sheet is completely// closed.final void Function()? onHide;overrideStateDragGestureBottomSheet createState() _DragGestureBottomSheetState(); }class _DragGestureBottomSheetState extends StateDragGestureBottomSheet {bool? isDragDirectionUp;double yBottomOffset 0.0;bool isDraggable false;bool isCompleteHide false;DragSheetController? dragSheetController;overridevoid initState() {// TODO: implement initStatedragSheetController DragSheetController();dragSheetController?.dispatch(widget.displayHeight);super.initState();}overridevoid dispose() {// TODO: implement disposedragSheetController?.dispose();super.dispose();}void _onVerticalDragUpdate(data) {if (widget.openDraggable) {print(data.delta.dy:${data.delta.dy});if (data.delta.dy 0) {// 向上isDragDirectionUp true;} else {// 向下isDragDirectionUp false;}yBottomOffset - data.delta.dy;if (yBottomOffset 0.0) {yBottomOffset 0.0;}if (yBottomOffset -widget.displayHeight) {yBottomOffset -widget.displayHeight;}double height widget.displayHeight yBottomOffset;dragSheetController?.dispatch(height);}}void _onVerticalDragEnd(data) {if (widget.openDraggable) {// 根据判断是否隐藏与显示if (false isDragDirectionUp) {if (yBottomOffset -widget.displayHeight / 3) {// 隐藏移除yBottomOffset -widget.displayHeight;isCompleteHide true;} else {yBottomOffset 0.0;isCompleteHide false;}} else {yBottomOffset 0.0;isCompleteHide false;}double height widget.displayHeight yBottomOffset;dragSheetController?.dispatch(height);}}void _onAniPositionedEnd(BuildContext context) {// 动画结束print(_onAniPositionedEnd);if (isCompleteHide) {// 隐藏则调用hidenif (widget.onHide ! null) {widget.onHide!.call();}} else {// 显示则调用showif (widget.onShow ! null) {widget.onShow!.call();}}if (isCompleteHide widget.autoNavigatorPop) {// 隐藏了则移除Navigator.of(context).pop();}}overrideWidget build(BuildContext context) {Size screenSize MediaQuery.of(context).size;return Column(mainAxisSize: MainAxisSize.min,children: Widget[RawGestureDetector(gestures: {_MyVerticalDragGestureRecognizer:GestureRecognizerFactoryWithHandlers_MyVerticalDragGestureRecognizer(() _MyVerticalDragGestureRecognizer(),(_MyVerticalDragGestureRecognizer recognizer) {recognizer..onStart (DragStartDetails details) {}..onUpdate (DragUpdateDetails details) {if (!isDraggable) {return;}_onVerticalDragUpdate(details);}..onEnd (DragEndDetails details) {_onVerticalDragEnd(details);};}),},child: StreamBuilder(stream: dragSheetController?.streamData,initialData: widget.displayHeight,builder: (_, snapshot) {return AnimatedContainer(curve: Curves.easeOut,duration: widget.duration,onEnd: () {_onAniPositionedEnd(context);},height: snapshot.data,width: screenSize.width,clipBehavior: Clip.hardEdge,decoration: const BoxDecoration(color: Colors.transparent,),child: NotificationListener(// 监听内部ListView的滑动变化onNotification: (ScrollNotification notification) {if (notification is OverscrollNotification notification.overscroll 0) {// 用户向下滑动ListView已经滑动到顶部处理GestureDetector的滑动事件isDraggable true;} else if (notification is ScrollUpdateNotification) {// 用户在ListView中执行滑动动作关闭外部GestureDetector的滑动处理isDraggable false;} else {}return false;},child: widget.child,),);},),)],);} }class _MyVerticalDragGestureRecognizer extends VerticalDragGestureRecognizer {overridevoid rejectGesture(int pointer) {// 单方面宣布自己胜出acceptGesture(pointer);} } 三、DragSheetController处理数据流 这里定义了DragSheetController来处理数据流DragSheetController中包括streamController、subscription、streamSink、streamData StreamBuilder是一个Widget它依赖Stream来做异步数据获取刷新widget。 Stream是一种用于异步处理数据流的机制它允许我们从一端发射一个事件从另外一端去监听事件的变化.Stream类似于JavaScript中的Promise、Swift中的Future或Java中的RxJava它们都是用来处理异步事件和数据的。Stream是一个抽象接口我们可以通过StreamController接口可以方便使用Stream。 使用详情请查看https://brucegwo.blog.csdn.net/article/details/136232000 最后DragSheetController代码如下 import dart:async;/// 处理Stream、StreamController相关逻辑 class DragSheetController {StreamSubscriptiondouble? subscription;//创建StreamControllerStreamControllerdouble? streamController StreamControllerdouble.broadcast();// 获取StreamSink用于发射事件StreamSinkdouble? get streamSink streamController?.sink;// 获取Stream用于监听Streamdouble? get streamData streamController?.stream;// Adds new values to streamsvoid dispatch(double value) {streamSink?.add(value);}// Closes streamsvoid dispose() {streamSink?.close();} } 通过DragSheetController当拖动时候高度发生变化时候会调用dispatch方法dispatch来发射数据流DragGestureBottomSheet中通过StreamBuilder来调整AnimatedContainer的高度。 最后调用使用DragGestureBottomSheet 我们使用showModalBottomSheet展示DragGestureBottomSheet时候 // 显示底部弹窗void showCustomBottomSheet(BuildContext context) {Size size MediaQuery.of(context).size;double displayHeight size.height - 88;showModalBottomSheet(context: context,isScrollControlled: true,builder: (ctx) {return DragGestureBottomSheet(displayHeight: displayHeight,autoNavigatorPop: true,openDraggable: true,onHide: () {print(onHide);},onShow: () {print(onShow);},child: Container(width: size.width,height: displayHeight,color: Colors.white,child: ScrollConfiguration(behavior: NoIndicatorScrollBehavior(),child: ListView.builder(itemCount: 20,physics: ClampingScrollPhysics(),itemBuilder: (context, index) {return GestureDetector(child: Container(width: size.width,height: 100,decoration: BoxDecoration(color: Colors.transparent,border: Border.all(color: Colors.black12,width: 0.25,style: BorderStyle.solid,),),child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [Text(index -- $index),SizedBox(width: 50,child: ClipOval(child:Image.asset(assets/images/hero_test.png)),),],),),onTap: () {Navigator.of(context).push(CupertinoPageRoute(builder: (BuildContext context) {return HeroPage();}));},);},),),),);},);} 效果图如下 https://brucegwo.blog.csdn.net/article/details/136241765 四、小结 flutter开发实战-手势Gesture与ListView滚动竞技场的可滑动关闭组件 学习记录每天不停进步。
http://www.zqtcl.cn/news/303893/

相关文章:

  • 网站与网页之间的区别是什么意思通过微信发布诱导分享的美文或者集赞活动属于哪种网络营销方式
  • 可信网站代码想学做网站从哪里入手
  • 做公众号选择图片的网站wordpress怎么看代码
  • 个人 中小企业公司网站建设方案百度网页版链接地址
  • 青岛网站推广方案网线制作心得与体会
  • 杭州网站优化公司哈尔滨企业网站模板建站
  • 洛阳免费网站建设自己做网站最新视频教程
  • 网站备案查询 美橙网开发app需要的技术
  • 软件产品如何做网站推广昆山外贸网站建设推广
  • 景德镇市城市建设规划网站wordpress用不了了
  • 网站及新媒体建设宣传片wordpress 无法编辑主题
  • 东莞设计网站重庆做腋臭骑士网站
  • 什么软件可以搜索关键词精准网站信息优化的方式
  • 购物网站排名前十名山东泰安建筑工程集团有限公司
  • 源码下载站用vs网站开发
  • 自己做网站seo彩票的网站怎么做
  • 如何在网站后台找到死链接网站内页权重查询
  • 专业做国际网站网站开发的编程软件
  • 如何运营垂直网站网页工具大全
  • 如何让自己做的网站可以播放歌曲做培训网站
  • 做网站的毕业设计网站没备案怎么做淘宝客
  • 百度申诉网站建设银行住房租赁代表品牌是什么
  • 网站初期推广方案虚拟服务器搭建wordpress
  • jeecms可以做网站卖吗山西网络推广专业
  • 2017 如何做网站优化育儿哪个网站做的好
  • 网站制作容易吗青岛网站建设公司报价
  • 淘宝建设网站的好处网站制作结构
  • 网站开发网站建设公司临沂网站建设找谁
  • 咋么做网站在电脑上潍坊免费模板建站
  • 苏州网站建设推广咨询平台做网站的公司图