flutter架 构项目基础

This commit is contained in:
崔宝新
2026-09-04 15:22:20 +08:00
parent 70967229d0
commit 0c5aee59c0
265 changed files with 35484 additions and 0 deletions
+167
View File
@@ -0,0 +1,167 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
/// ============================================================
/// GridView 网格布局演示页
///
/// 一、两种使用方式:
/// 1. 直接运行本页面:runApp(const MaterialApp(home: GridDemoPage()))
/// 2. 复制某段核心代码到任意 Scaffold 的 body 中。
///
/// 二、三个常用构造:
/// GridView.count : 固定列数,写死 children(一次性全部创建)
/// GridView.builder : 懒加载,itemCount + itemBuilder,大量数据首选
/// GridView.extent : 按"每项最大宽度"自适应列数(屏幕越宽列越多)
///
/// 三、核心参数:
/// crossAxisCount : 列数(GridView.count 专用)
/// maxCrossAxisExtent: 每项最大宽度(GridView.extent 专用)
/// mainAxisSpacing : 主轴(上下行)间距
/// crossAxisSpacing : 交叉轴(左右列)间距
/// childAspectRatio : 每项 宽:高 比例,默认 1(正方形)
///
/// 四、高频坑:
/// 1. GridView 放 Column 必须 SizedBox 定高或 Expanded(同 ListView);
/// 2. childAspectRatio 太小(如 0.5)时文字会被挤压溢出,调比例或缩小字号。
///
/// 五、和 CustomScrollView(Sliver) 的本质区别(重点记忆):
/// GridView = CustomScrollView + 1 个 SliverGrid(框架内部自动包的)。
/// SDK 源码:GridView extends BoxScrollView,而 ScrollView.build()
/// 返回的就是 CustomScrollView——所以 GridView 是"只有网格这一种内容"
/// 的简化套餐,两者都是"单个滚动 + 懒加载"。
/// · 页面只有网格 → body: GridView.builder(...) 直接用
/// · 页面要混排 AppBar + 网格 + 列表 → CustomScrollView + slivers
/// · 本页外层 SingleChildScrollView 只是"展示台":为并排演示 3 种构造,
/// 内部塞的是固定高 GridView(嵌套滚动)。真实网格页别学这个外层!
/// ============================================================
class GridDemoPage extends StatelessWidget {
const GridDemoPage({super.key});
// 网格配色(循环使用)
static const List<Color> _colors = [
Color(0xFF3B82F6), Color(0xFF8E6FE8), Color(0xFFF05252),
Color(0xFFFF9800), Color(0xFF4CAF50), Color(0xFF00BCD4),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('GridView 网格 Demo')),
body: SingleChildScrollView(
padding: EdgeInsets.all(16.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const _SectionTitle('Demo1:GridView.count 固定 3 列'),
Text(
'写死 children,一次性全创建,适合少量固定网格',
style: TextStyle(fontSize: 13.sp, color: Color(0xFF888888)),
),
SizedBox(height: 8.h),
SizedBox(
height: 260.h,
child: GridView.count(
crossAxisCount: 3, // 列数
mainAxisSpacing: 8.w, // 上下间距
crossAxisSpacing: 8.w, // 左右间距
childAspectRatio: 1, // 宽:高 = 1:1 正方形
children: [
for (int i = 0; i < 12; i++) _GridItem(index: i),
],
),
),
SizedBox(height: 32.h),
const _SectionTitle('Demo2:GridView.builder 懒加载'),
Text(
'itemCount: 100,只创建可见的格子,滚到哪建到哪',
style: TextStyle(fontSize: 13.sp, color: Color(0xFF888888)),
),
SizedBox(height: 8.h),
SizedBox(
height: 260.h,
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4, // 4 列小格子
mainAxisSpacing: 8.w,
crossAxisSpacing: 8.w,
childAspectRatio: 1,
),
itemCount: 100, // 假装 100 个格子
itemBuilder: (context, index) => _GridItem(index: index),
),
),
SizedBox(height: 32.h),
const _SectionTitle('Demo3:GridView.extent 自适应列宽'),
Text(
'maxCrossAxisExtent: 120 → 每项最多 120 宽,屏幕越宽列数自动变多',
style: TextStyle(fontSize: 13.sp, color: Color(0xFF888888)),
),
SizedBox(height: 8.h),
SizedBox(
height: 260.h,
child: GridView.extent(
maxCrossAxisExtent: 80.w, // 每项最多 80 宽
mainAxisSpacing: 8.w,
crossAxisSpacing: 8.w,
childAspectRatio: 1,
children: [
for (int i = 0; i < 12; i++) _GridItem(index: i),
],
),
),
],
),
),
);
}
}
/// 单个网格项:彩色方块 + 序号
class _GridItem extends StatelessWidget {
const _GridItem({required this.index});
final int index;
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: GridDemoPage._colors[index % GridDemoPage._colors.length],
borderRadius: BorderRadius.circular(8.r),
),
alignment: Alignment.center,
child: Text(
'$index',
style: TextStyle(
color: Colors.white,
fontSize: 18.sp,
fontWeight: FontWeight.bold,
),
),
);
}
}
/// 区块标题
class _SectionTitle extends StatelessWidget {
const _SectionTitle(this.title);
final String title;
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(bottom: 4.h),
child: Text(
title,
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.bold,
color: Color(0xFF333333),
),
),
);
}
}