import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
// Flutter 提供的一个调试开关,用来在界面上直观显示每个组件的边界和布局信息,帮助开发者检查 UI 布局问题。开启后,所有 RenderBox 会绘制边框和辅助线.
debugPaintSizeEnabled = true;
runApp(const MyApp());
}
// StatelessWidget: 在构建完成后不会随时间或交互而改变。它适合用来展示始终固定的 UI,比如文本、图标或按钮.
// Scaffold: Flutter 提供的一个 页面骨架容器,用来快速搭建常见的 Material Design 布局结构. 它提供了 AppBar、Drawer、BottomNavigationBar 等常用组件.
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: const Text('Flutter Demo Home Page'),
),
body: Center(
child: _buildImageColumn()),
),
);
}
// decoration: Container 的一个属性,用来定义背景、边框、阴影、渐变等视觉效果.
// BoxDecoration:专门用于矩形区域的装饰类,可以设置颜色、圆角、边框、渐变、图片背景等
Widget _buildImageColumn() {
return Container(
decoration: const BoxDecoration(color: Colors.black26),
// children: [...] 属性接收一个 Widget 列表,这些子组件会从上到下依次排列
child: Column(children:[_buildImageRow(1), _buildImageRow(3)]),
);
}
// Expanded 是一个布局组件,用在 Row 或 Column 中,会让子组件在主轴方向上尽可能扩展,占据剩余空间.
// Widget _buildDecoratedImage(int imageIndex) => Expanded(...);
// 等价于
// Widget _buildDecoratedImage(int imageIndex) {
// return Expanded(...);
// }
Widget _buildDecoratedImage(int imageIndex) => Expanded(
child: Container(
decoration: BoxDecoration(
// 给容器加上宽度为 10 的灰黑色边框。
border:Border.all(width:10, color:Colors.black38),
// 给容器四个角加上 8 像素的圆角.
borderRadius: const BorderRadius.all(Radius.circular(8))
),
// 设置容器外部的间距,这里是四周各 4 像素。
margin: const EdgeInsets.all(4),
child:Image.asset('images/pic$imageIndex.png'),
),
);
Widget _buildImageRow(int imageIndex) => Row(
children: [
_buildDecoratedImage(imageIndex),
_buildDecoratedImage(imageIndex + 1),
],
);
}
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
debugPaintSizeEnabled = true;
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'flutter layout demo',
home: Scaffold(
appBar: AppBar(
title: const Text('Flutter Demo Home Page'),
),
body: Center(
child: showGrid ? _buildGrid() : _buildList()
)
),
);
}
}
// GridView.extent: Flutter 提供的一种网格布局构造方式,它会根据你给定的 最大交叉轴宽度(maxCrossAxisExtent) 自动计算每行能放多少个元素.
Widget _buildGrid() => GridView.extent(
// maxCrossAxisExtent: 150 表示每个网格项的最大宽度是 150 像素.
maxCrossAxisExtent: 150,
// 整个 GridView 四周留 4 像素的内边距
padding: const EdgeInsets.all(4),
// mainAxisSpacing: 4 → 主轴(竖向)每个格子之间的间距是 4 像素
mainAxisSpacing: 4,
// crossAxisSpacing: 4 → 交叉轴(水平方向)每个格子之间的间距是 4 像素
crossAxisSpacing: 4,
children: _buildGridTileList(30)
);
List<Widget> _buildGridTileList(int count) => List.generate(count, (int index) => GridTile(
child: Image.asset('images/pic${index % 3 + 1}.png'),
footer: Container(
color: Colors.black54,
child: Text('grid item $index', style: const TextStyle(color: Colors.white)),
),
));
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
debugPaintSizeEnabled = true;
runApp(const MyApp());
}
class MyApp extends StatelessWidget{
const MyApp({super.key});
@override
Widget build(BuildContext context) {
const String appTitle = "Flutter layout demo";
return MaterialApp(
title: appTitle,
home: Scaffold(
// 顶部栏组件, 通常包含标题, 菜单按钮, 操作按钮等.
appBar: AppBar(
title: const Text(appTitle),
),
body: const SingleChildScrollView(
child:Column(
children: [
TitleSection(
name: 'Oeschinen Lake Campground'
, location: 'Kandersteg, Switzerland'
),
],
),
),
),
);
}
}
class TitleSection extends StatelessWidget {
// {super.key} 是 Dart 语言中的一个语法糖,用于将子类的构造函数参数传递给父类的构造函数。
const TitleSection({super.key, required this.name, required this.location});
final String name;
final String location;
@override
Widget build(BuildContext context) {
return Padding(
// padding: const EdgeInsets.all(32),
padding: const EdgeInsets.fromLTRB(32, 32, 32, 0),
child: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(bottom:8),
child: Text(
name,
style: const TextStyle(fontWeight: FontWeight.bold)
),
),
Text(location, style:TextStyle(color:Colors.grey[500])),
],
)
),
Icon(Icons.start, color:Colors.red[500]),
const Text('41'),
],
)
);
}
}
class ButtonSection extends StatelessWidget {
const ButtonSection({super.key});
@override
Widget build(BuildContext context) {
final Color color = Theme.of(context).primaryColor;
}
}
class ButtonWithText extends StatelessWidget {
const ButtonWithText({super.key, required this.color, required this.icon, required this.label,});
final Color color;
final IconData icon;
final String label;
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(icon, color:color),
Container(
margin: const EdgeInsets.only(top:8),
child: Text(label, style: TextStyle(fontSize:12, fontWeight:FontWeight.w400, color:color)),
)
],
)
}
}