Flutter---CustomScrollView的UI项目(1) 效果图详细介绍整体分为3个部分一个是顶部固定的信息栏一个是滑动的列表还有一个是底部固定的播放栏。重点内容// 理解基础布局组件 Stack( // 层叠布局背景内容底部栏 children: [ Container(), // 背景层 CustomScrollView(), // 内容滚动层 Positioned() // 底部固定层 ], ) // 理解滚动布局 CustomScrollView( slivers: [ SliverAppBar(), // 固定头部 SliverToBoxAdapter(), // 列表内容 ], ) // 理解组件封装 Widget buildItem({ // 参数化组件 required String title, required String icon, VoidCallback? callback }) { return Container(...); } // 理解状态管理 class SleepPage extends StatefulWidget { override StateStatefulWidget createState() _SleepPage(); }实现步骤1.背景渐变Container( width: double.infinity, height: double.infinity, decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Colors.white, Colors.purple.withOpacity(0.7), ], ), ), ),2.可滚动的内容CustomScrollView( slivers: [ // 顶部信息固定区域 SliverAppBar( expandedHeight: 270, //展开高度 collapsedHeight: 270, //收起高度与展开相同固定高度 pinned: true, //固定在顶部不让滑动 snap: false, floating: false, automaticallyImplyLeading: false, backgroundColor: Colors.transparent, elevation: 0, flexibleSpace: Stack( //实际内容区 children: [ //背景容器 Positioned.fill( child: Image.asset( assets/images/start.png, fit: BoxFit.cover, ), ), // 标题行 Positioned( top:50, left: 10, right: 0, child: Row( children: [ SizedBox(width: 20), GestureDetector( onTap: () Navigator.pop(context), child: Image.asset(assets/images/back_white.png,width: 20,height: 20,), ), Spacer(), Text( 标题栏, style: TextStyle(color: Colors.white, fontSize: 24), ), Spacer(), SizedBox(width: 20), ], ), ), // 耳机图 Positioned( top: 109, left: 0, right: 0, child: Container( height: 141, child: Image.asset( assets/images/earphone.png, fit: BoxFit.contain, ), ), ), ], ), ), // 内容列表 SliverToBoxAdapter( child: Column( children: [ buildItem( title: 列表1, icon: assets/images/apple.png, rightIcon: assets/images/apple.png, ), const SizedBox(height: 8), buildItem( title: 列表2, icon: assets/images/apple.png, rightIcon: assets/images/apple.png, ), const SizedBox(height: 8), buildItem( title: 列表3, icon: assets/images/apple.png, rightIcon: assets/images/apple.png, ), const SizedBox(height: 8), buildItem( title: 列表4, icon: assets/images/apple.png, rightIcon: assets/images/apple.png, ), const SizedBox(height: 8), buildItem( title: 列表5, icon: assets/images/apple.png, rightIcon: assets/images/apple.png, ), const SizedBox(height: 8), buildItem( title: 列表6, icon: assets/images/apple.png, rightIcon: assets/images/apple.png, ), const SizedBox(height: 8), buildItem( title: 列表7, icon: assets/images/apple.png, rightIcon: assets/images/apple.png, ), const SizedBox(height: 8), buildItem( title: 列表8, icon: assets/images/apple.png, rightIcon: assets/images/apple.png, ), const SizedBox(height: 8), buildItem( title: 列表9, icon: assets/images/apple.png, rightIcon: assets/images/apple.png, ), const SizedBox(height: 8), // 添加底部间距为固定播放栏留出空间 const SizedBox(height: 80), // 播放栏高度 边距 ], ), ), ], ),3.固定在底部的播放栏Positioned( left: 10, right: 15, bottom: 15, // 距离底部的距离 child: Container( height: 60, padding: const EdgeInsets.symmetric(horizontal: 20), decoration: BoxDecoration( color: const Color(0xFF2C2C2E), borderRadius: BorderRadius.circular(10), ), child: Row( children: [ Image.asset(assets/images/cherry.png,), const SizedBox(width: 10), const Text( Rain, style: TextStyle(color: Colors.white), ), const Spacer(), Image.asset(assets/images/mango.png,), const SizedBox(width: 10), Image.asset(assets/images/banana.png), ], ), ), ),4.小卡片的通用组件Widget buildItem({ required String title, required String icon, required String rightIcon, VoidCallback? callback }) { return Container( padding: EdgeInsets.symmetric(horizontal: 20), margin: EdgeInsets.only(left: 15,right: 20), height: 52, width: double.infinity, decoration:BoxDecoration( color: Colors.white.withOpacity(0.1), borderRadius: BorderRadius.circular(10), ), child: Material( color: Colors.transparent, child: Ink( child: InkWell( onTap: callback, child: Row( children: [ Image.asset(icon), SizedBox(width: 15,), Text(title,style: const TextStyle(color: Colors.white,fontSize: 18),), const Expanded(child: SizedBox()), Image.asset(rightIcon), ], ) ), ), ) ); }代码实例import package:flutter/cupertino.dart; import package:flutter/material.dart; class SleepPage extends StatefulWidget { const SleepPage({super.key}); override StateStatefulWidget createState() _SleepPage(); } class _SleepPage extends StateSleepPage { override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.transparent, body: Stack( children: [ //1.背景渐变 Container( width: double.infinity, height: double.infinity, decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Colors.white, Colors.purple.withOpacity(0.7), ], ), ), ), // 2. 可滚动内容 CustomScrollView( slivers: [ // 顶部信息固定区域 SliverAppBar( expandedHeight: 270, //展开高度 collapsedHeight: 270, //收起高度与展开相同固定高度 pinned: true, //固定在顶部不让滑动 snap: false, floating: false, automaticallyImplyLeading: false, backgroundColor: Colors.transparent, elevation: 0, flexibleSpace: Stack( //实际内容区 children: [ //背景容器 Positioned.fill( child: Image.asset( assets/images/start.png, fit: BoxFit.cover, ), ), // 标题行 Positioned( top:50, left: 10, right: 0, child: Row( children: [ SizedBox(width: 20), GestureDetector( onTap: () Navigator.pop(context), child: Image.asset(assets/images/back_white.png,width: 20,height: 20,), ), Spacer(), Text( 标题栏, style: TextStyle(color: Colors.white, fontSize: 24), ), Spacer(), SizedBox(width: 20), ], ), ), // 耳机图 Positioned( top: 109, left: 0, right: 0, child: Container( height: 141, child: Image.asset( assets/images/earphone.png, fit: BoxFit.contain, ), ), ), ], ), ), // 内容列表 SliverToBoxAdapter( child: Column( children: [ buildItem( title: 列表1, icon: assets/images/apple.png, rightIcon: assets/images/apple.png, ), const SizedBox(height: 8), buildItem( title: 列表2, icon: assets/images/apple.png, rightIcon: assets/images/apple.png, ), const SizedBox(height: 8), buildItem( title: 列表3, icon: assets/images/apple.png, rightIcon: assets/images/apple.png, ), const SizedBox(height: 8), buildItem( title: 列表4, icon: assets/images/apple.png, rightIcon: assets/images/apple.png, ), const SizedBox(height: 8), buildItem( title: 列表5, icon: assets/images/apple.png, rightIcon: assets/images/apple.png, ), const SizedBox(height: 8), buildItem( title: 列表6, icon: assets/images/apple.png, rightIcon: assets/images/apple.png, ), const SizedBox(height: 8), buildItem( title: 列表7, icon: assets/images/apple.png, rightIcon: assets/images/apple.png, ), const SizedBox(height: 8), buildItem( title: 列表8, icon: assets/images/apple.png, rightIcon: assets/images/apple.png, ), const SizedBox(height: 8), buildItem( title: 列表9, icon: assets/images/apple.png, rightIcon: assets/images/apple.png, ), const SizedBox(height: 8), // 添加底部间距为固定播放栏留出空间 const SizedBox(height: 80), // 播放栏高度 边距 ], ), ), ], ), // 3. 固定在底部的播放栏 Positioned( left: 10, right: 15, bottom: 15, // 距离底部的距离 child: Container( height: 60, padding: const EdgeInsets.symmetric(horizontal: 20), decoration: BoxDecoration( color: const Color(0xFF2C2C2E), borderRadius: BorderRadius.circular(10), ), child: Row( children: [ Image.asset(assets/images/cherry.png,), const SizedBox(width: 10), const Text( Rain, style: TextStyle(color: Colors.white), ), const Spacer(), Image.asset(assets/images/mango.png,), const SizedBox(width: 10), Image.asset(assets/images/banana.png), ], ), ), ), ], ), ); } //功能小卡片 Widget buildItem({ required String title, required String icon, required String rightIcon, VoidCallback? callback }) { return Container( padding: EdgeInsets.symmetric(horizontal: 20), margin: EdgeInsets.only(left: 15,right: 20), height: 52, width: double.infinity, decoration:BoxDecoration( color: Colors.white.withOpacity(0.1), borderRadius: BorderRadius.circular(10), ), child: Material( color: Colors.transparent, child: Ink( child: InkWell( onTap: callback, child: Row( children: [ Image.asset(icon), SizedBox(width: 15,), Text(title,style: const TextStyle(color: Colors.white,fontSize: 18),), const Expanded(child: SizedBox()), Image.asset(rightIcon), ], ) ), ), ) ); } }