一 电子商务网站建设规划wordpress摘要显示图片

张小明 2026/1/11 9:33:59
一 电子商务网站建设规划,wordpress摘要显示图片,装修店铺,青岛网站建设哪家专业效果图 数据流 原始数据 (carouselItems) ↓ 包装 无限循环数据 (infiniteItems) ↓ 传递 PageView.builder → 渲染图片 核心组件 1. PageController 核心控制器#xff0c;管理页面滚动viewportFraction: 1.0#xff1a;每页占满屏幕initialPage: 1#xff1a;从真实第…效果图数据流原始数据 (carouselItems) ↓ 包装 无限循环数据 (infiniteItems) ↓ 传递 PageView.builder → 渲染图片核心组件1. PageController 核心控制器管理页面滚动 viewportFraction: 1.0每页占满屏幕 initialPage: 1从真实第一张开始 2. PageView.builder 懒加载构建页面 支持无限滚动 与PageController配合 3. AnimatedContainer 实现指示器动画效果 自动处理属性变化的动画无限循环轮播图的核心技巧1.假设原始数据有3张图片carouselItems [A, B, C] 2.扩展数据 infiniteItems [ carouselItems.last, // C ← 最后一张放在最前面 ...carouselItems, // A, B, C ← 原始数据 carouselItems.first, // A ← 第一张放在最后面 ] 得到 索引: 0 1 2 3 4 数据: [C] [A] [B] [C] [A] 3.初始状态 用户看到的 [A] [B] [C] 实际数据 [C] [A] [B] [C] [A] ↑ ↑ ↑ ↑ ↑ 索引 0 1 2 3 4 当前显示 (索引1显示A) 4.非边界滑动情况 滑动前 [C] [A] [B] [C] [A] 显示A (索引1) 滑动后 [C] [A] [B] [C] [A] 显示B (索引2) 5.滑动到最左边边界当用户从A(索引1)向左滑到C(索引0)时 滑动后 [C] [A] [B] [C] [A] 显示C (索引0) 此时程序检测到索引0 0边界条件 立即跳转到索引3也是C 跳转后 [C] [A] [B] [C] [A] 显示C (索引3) 6.滑动到最右边边界当用户从C(索引3)向右滑到A(索引4)时 滑动后 [C] [A] [B] [C] [A] 显示A (索引4) 此时程序检测到索引4 数组长度-1 立即跳转到索引1也是A 跳转后 [C] [A] [B] [C] [A] 显示A (索引1)代码逻辑对应void _onPageChanged(int index) { if (index 0) { // 滑到了最左边的假C _pageController.jumpToPage(3); // 跳转到最右边的真C _currentIndex 2; // 显示原始数据的最后一项(索引2) } else if (index 4) { // 滑到了最右边的假A _pageController.jumpToPage(1); // 跳转到最左边的真A _currentIndex 0; // 显示原始数据的第一项(索引0) } else { // 正常滑动 _currentIndex index - 1; // 减去前面的假C } }实现步骤1.准备图片//轮播图数据 final ListString carouselItems [ assets/images/apple.png, assets/images/banana.png, assets/images/cherry.png, ];2.定义一些必要的变量late PageController _pageController; //核心控制器 int _currentIndex 1; // 从原始数据的第一个开始注意索引1对应原始数据的第一个 Timer? _timer;//定时器3.为了实现无缝循环扩展图片数据//实现无缝循环 ListString get infiniteItems { return [ carouselItems.last, // 最后一项放在最前面 ...carouselItems, // 原始数据 carouselItems.first, // 第一项放在最后面 ]; }4.初始化override void initState() { super.initState(); //初始胡控制器 _pageController PageController( viewportFraction: 1.0, //每个页面占视口的比例0.0~1.0 initialPage: 1, //初始显示第几页 ); _startAutoPlay(); //开始自动播放 }5.注销控制器override void dispose() { _timer?.cancel(); _pageController.dispose(); super.dispose(); }6.开始自动播放的方法//开始自动播放 void _startAutoPlay() { //Timer.periodic:创建一个周期性定时器 _timer Timer.periodic(const Duration(seconds: 3), (timer) { //每3秒执行一次回调函数 //页面安全判断 if (!mounted) return; //页面切换 _pageController.nextPage( //切换下一页的方法 duration: const Duration(milliseconds: 800), //动画持续时间 curve: Curves.fastOutSlowIn,//动画曲线为 先加速后减速 ); }); }7.页面切换的回调函数//页面切换的回调函数 void _onPageChanged(int index) { // 处理边界情况实现无缝循环 if (index 0) { // 如果滚动到虚拟的第一页实际是原始数据的最后一页 // 无动画跳转到真实数据的最后一页 _pageController.jumpToPage(carouselItems.length); setState(() { _currentIndex carouselItems.length - 1; // 显示指示器为最后一页 }); } else if (index infiniteItems.length - 1) { // 如果滚动到虚拟的最后一页实际是原始数据的第一页 // 无动画跳转到真实数据的第一页 _pageController.jumpToPage(1); setState(() { _currentIndex 0; // 显示指示器为第一页 }); } else { // 正常页面变化 setState(() { _currentIndex index - 1; // 转换为原始数据的索引 }); } }8.暂停播放和继续播放//暂停自动播放 void _pauseAutoPlay() { _timer?.cancel(); } //继续自动播放 void _resumeAutoPlay() { _timer?.cancel(); _startAutoPlay(); }9.轮播图的核心*******// 轮播图区域 SizedBox( height: 142, // 固定高度 child: PageView.builder( controller: _pageController, //控制器 onPageChanged: _onPageChanged,//页面切换回调 itemCount: infiniteItems.length, //总页数 physics: const ClampingScrollPhysics(), //滚动物理效果 itemBuilder: (context, index) { return GestureDetector( onTap: () { // 计算真实数据的索引 int realIndex index - 1; if (realIndex 0) realIndex carouselItems.length - 1; if (realIndex carouselItems.length) realIndex 0; _handleCarouselTap(realIndex); }, onTapDown: (_) _pauseAutoPlay(), //按下时暂停自动播放 onTapCancel: () _resumeAutoPlay(), //取消点击时恢复 onTapUp: (_) _resumeAutoPlay(), //抬起时恢复 child: Container( margin: EdgeInsets.symmetric(horizontal: 20), decoration: BoxDecoration( image: DecorationImage( image: AssetImage(infiniteItems[index]), fit: BoxFit.contain, ), ), ), ); }, ), ),10.分页指示器的实现// 分页指示器 Container( margin: const EdgeInsets.only(top: 10), // 距离上方10像素的外边距 height: 20, // 容器高度20像素 child: Row( // 水平排列子组件 mainAxisAlignment: MainAxisAlignment.center, // 子组件水平居中 children: List.generate( // 动态生成指示点列表 carouselItems.length, // 根据轮播图数量生成 (index) AnimatedContainer( // 每个指示点是一个动画容器 duration: const Duration(milliseconds: 300), // 动画持续时间300ms width: _currentIndex index ? 20 : 8, // 当前激活点宽20其他宽8 height: 8, // 所有点高度固定为8 margin: const EdgeInsets.symmetric(horizontal: 4), // 左右间距4像素 decoration: BoxDecoration( shape: BoxShape.circle, // 圆形形状 color: _currentIndex index // 颜色激活点蓝色其他灰色 ? Colors.blue : Colors.grey.withOpacity(0.3), ), ), ), ), ),11.单击的方法void _handleCarouselTap(int index) { print(点击了: ${carouselItems[index]}); }代码实例import dart:async; import package:flutter/cupertino.dart; import package:flutter/material.dart; class DialMain extends StatefulWidget { const DialMain({super.key}); override StateStatefulWidget createState() _DialMainState(); } class _DialMainState extends StateDialMain with SingleTickerProviderStateMixin { //轮播图数据 final ListString carouselItems [ assets/images/apple.png, assets/images/banana.png, assets/images/cherry.png, ]; late PageController _pageController; //核心控制器 int _currentIndex 1; // 从原始数据的第一个开始注意索引1对应原始数据的第一个 Timer? _timer;//定时器 //实现无缝循环 ListString get infiniteItems { return [ carouselItems.last, // 最后一项放在最前面 ...carouselItems, // 原始数据 carouselItems.first, // 第一项放在最后面 ]; } override void initState() { super.initState(); //初始胡控制器 _pageController PageController( viewportFraction: 1.0, //每个页面占视口的比例0.0~1.0 initialPage: 1, //初始显示第几页 ); _startAutoPlay(); //开始自动播放 } override void dispose() { _timer?.cancel(); _pageController.dispose(); super.dispose(); } //开始自动播放 void _startAutoPlay() { //Timer.periodic:创建一个周期性定时器 _timer Timer.periodic(const Duration(seconds: 3), (timer) { //每3秒执行一次回调函数 //页面安全判断 if (!mounted) return; //页面切换 _pageController.nextPage( //切换下一页的方法 duration: const Duration(milliseconds: 800), //动画持续时间 curve: Curves.fastOutSlowIn,//动画曲线为 先加速后减速 ); }); } //页面切换的回调函数 void _onPageChanged(int index) { // 处理边界情况实现无缝循环 if (index 0) { // 如果滚动到虚拟的第一页实际是原始数据的最后一页 // 无动画跳转到真实数据的最后一页 _pageController.jumpToPage(carouselItems.length); setState(() { _currentIndex carouselItems.length - 1; // 显示指示器为最后一页 }); } else if (index infiniteItems.length - 1) { // 如果滚动到虚拟的最后一页实际是原始数据的第一页 // 无动画跳转到真实数据的第一页 _pageController.jumpToPage(1); setState(() { _currentIndex 0; // 显示指示器为第一页 }); } else { // 正常页面变化 setState(() { _currentIndex index - 1; // 转换为原始数据的索引 }); } } //暂停自动播放 void _pauseAutoPlay() { _timer?.cancel(); } //继续自动播放 void _resumeAutoPlay() { _timer?.cancel(); _startAutoPlay(); } override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFFF7F7F9), appBar: AppBar( backgroundColor: const Color(0xFFF7F7F9), title: const Text(轮播图), centerTitle: true, leading: IconButton( onPressed: () Navigator.pop(context), icon: const Icon(Icons.arrow_back_ios, color: Colors.black), ), ), body: Column( children: [ // 轮播图区域 SizedBox( height: 142, // 固定高度 child: PageView.builder( controller: _pageController, //控制器 onPageChanged: _onPageChanged,//页面切换回调 itemCount: infiniteItems.length, //总页数 physics: const ClampingScrollPhysics(), //滚动物理效果 itemBuilder: (context, index) { return GestureDetector( onTap: () { // 计算真实数据的索引 int realIndex index - 1; if (realIndex 0) realIndex carouselItems.length - 1; if (realIndex carouselItems.length) realIndex 0; _handleCarouselTap(realIndex); }, onTapDown: (_) _pauseAutoPlay(), //按下时暂停自动播放 onTapCancel: () _resumeAutoPlay(), //取消点击时恢复 onTapUp: (_) _resumeAutoPlay(), //抬起时恢复 child: Container( margin: EdgeInsets.symmetric(horizontal: 20), decoration: BoxDecoration( image: DecorationImage( image: AssetImage(infiniteItems[index]), fit: BoxFit.contain, ), ), ), ); }, ), ), // 分页指示器 Container( margin: const EdgeInsets.only(top: 10), // 距离上方10像素的外边距 height: 20, // 容器高度20像素 child: Row( // 水平排列子组件 mainAxisAlignment: MainAxisAlignment.center, // 子组件水平居中 children: List.generate( // 动态生成指示点列表 carouselItems.length, // 根据轮播图数量生成 (index) AnimatedContainer( // 每个指示点是一个动画容器 duration: const Duration(milliseconds: 300), // 动画持续时间300ms width: _currentIndex index ? 20 : 8, // 当前激活点宽20其他宽8 height: 8, // 所有点高度固定为8 margin: const EdgeInsets.symmetric(horizontal: 4), // 左右间距4像素 decoration: BoxDecoration( shape: BoxShape.circle, // 圆形形状 color: _currentIndex index // 颜色激活点蓝色其他灰色 ? Colors.blue : Colors.grey.withOpacity(0.3), ), ), ), ), ), const SizedBox(height: 20), ], ), ); } void _handleCarouselTap(int index) { print(点击了: ${carouselItems[index]}); } }
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

唐山制作网站的公司咖啡seo是什么意思

3Dmol.js 完整指南:从零开始掌握分子可视化 【免费下载链接】3Dmol.js WebGL accelerated JavaScript molecular graphics library 项目地址: https://gitcode.com/gh_mirrors/3d/3Dmol.js 3Dmol.js 是一个基于 WebGL 技术的 JavaScript 分子可视化库&#x…

张小明 2026/1/9 7:47:09 网站建设

长春商城网站开发新浪微博可以做网站吗

NGA论坛作为国内知名的游戏社区,其丰富的讨论内容吸引了大量用户。然而,面对繁杂的界面元素和信息干扰,如何高效地获取有价值的内容成为了许多用户的痛点。NGA-BBS-Script应运而生,这款功能强大的用户脚本通过全面的界面优化和智能…

张小明 2026/1/9 7:47:07 网站建设

古云网站建设网站建设与管理课后总结

大文件上传方案探索:从WebUploader到自定义分片上传的实践 作为一名前端开发工程师,最近遇到了一个颇具挑战性的需求:需要在Vue项目中实现4GB左右大文件的稳定上传,且要兼容Chrome、Firefox、Edge等主流浏览器,后端使…

张小明 2026/1/9 7:47:05 网站建设

深圳网站建设注意事项金华seo全网营销

第一章:Docker与eBPF安全增强的演进背景随着容器化技术在生产环境中的广泛部署,Docker已成为构建和运行云原生应用的核心组件。然而,其轻量级隔离机制在提供高效资源利用的同时,也引入了新的安全挑战。传统Linux内核的访问控制机制…

张小明 2026/1/9 7:47:02 网站建设

织梦网站地图什么样的网站结构适合做seo

LobeChat 容器化迁移方案 在 AI 技术加速落地的今天,大语言模型(LLM)已不再是实验室里的概念,而是逐步渗透进企业服务、个人助手乃至日常办公的核心工具。然而,面对 OpenAI、Anthropic、通义千问、Ollama 等众多模型平…

张小明 2026/1/9 7:47:00 网站建设

字体设计网站有哪些平凉网站建设

Linux 常用命令与操作指南 1. 系统特殊组合键功能 在 Linux 系统中,有一些特殊的组合键可以实现特定的系统操作,以下为您详细介绍: |组合键|功能描述| | ---- | ---- | | |向除 init 之外的所有运行进程发送 KILL 信号,可能比之前的组合键更能成功杀死失控进程,但可…

张小明 2026/1/9 12:32:46 网站建设