页面尺寸
- 通知栏高度:
MediaQuery.of(context).padding.top
- 顶部导航高度:
kToolbarHeight
- 底部导航高度:
kBottomNavigationBarHeight
- 屏幕宽:
MediaQuery.of(context).size.width
- 屏幕高:
MediaQuery.of(context).size.height
import 'package:flutter/material.dart';
// 描述文本
class DescText extends StatelessWidget {
final String title;
final double size;
const DescText(this.title, {super.key, this.size = 10});
Widget build(BuildContext context) {
return Center(
child: Text(title, style: TextStyle(fontSize: size, decoration: TextDecoration.none)),
);
}
}
class ScreenSizePage extends StatefulWidget {
const ScreenSizePage({super.key});
State<ScreenSizePage> createState() => _ScreenSizePage();
}
class _ScreenSizePage extends State<ScreenSizePage> {
Widget build(BuildContext context) {
// 屏幕宽度
double screenWidth = MediaQuery
.of(context)
.size
.width;
// 屏幕高度
double screenHeight = MediaQuery
.of(context)
.size
.height;
// 通知栏高度
double noticeHeight = MediaQuery
.of(context)
.padding
.top;
// 屏幕中心
double centerX = screenWidth / 2;
double centerY = screenHeight / 2;
return Container(
width: double.infinity,
height: double.infinity,
color: Colors.grey,
child: Stack(
children: [
Positioned(
top: 0,
left: 0,
child: Container(
width: screenWidth,
height: noticeHeight,
color: Colors.yellow,
child: DescText('通知栏高度($noticeHeight):MediaQuery.of(context).padding.top'),
),
),
Positioned(
top: noticeHeight,
left: 0,
child: Container(
width: screenWidth,
height: kToolbarHeight,
color: Colors.blue,
child: const DescText('顶部导航高度($kToolbarHeight):kToolbarHeight', size: 16),
),
),
Positioned(
bottom: 0,
left: 0,
child: Container(
width: screenWidth,
height: kBottomNavigationBarHeight,
color: Colors.green,
child: const DescText(
'底部导航高度($kBottomNavigationBarHeight):kBottomNavigationBarHeight', size: 14),
),
),
Positioned(
bottom: 80,
left: 0,
child: Container(
width: screenWidth,
height: 30,
color: const Color.fromRGBO(255, 255, 0, .3),
child: DescText('屏幕宽($screenWidth):MediaQuery.of(context).size.width'),
),
),
Positioned(
top: 0,
right: 80,
child: Container(
width: 30,
height: screenHeight,
color: const Color.fromRGBO(0, 255, 255, .3),
child: RotatedBox(
quarterTurns: 45,
child: DescText(
'屏幕高($screenHeight):MediaQuery.of(context).size.height', size: 12),
),
),
),
Positioned(
top: centerY - 18,
left: centerX - 50,
child: MaterialButton(
onPressed: () => Navigator.pop(context, true),
// 返回上一页
color: Colors.white,
textColor: Colors.blue,
minWidth: 100,
height: 36,
child: const Text('返 回'),
),
),
],
),
);
}
}
Stack布局
SelectWidget
组件参考 https://blog.csdn.net/weixin_43526371/article/details/136256386
import 'package:flutter/material.dart';
import 'package:flutter_app/components/select_widget.dart';
class StackPage extends StatefulWidget {
const StackPage({super.key});
State<StackPage> createState() => _StackPage();
}
class _StackPage extends State<StackPage> {
AlignmentDirectional alignmentValue = AlignmentDirectional.topStart;
List<SelectOption> alignmentList = [
SelectOption(label: 'topStart', value: AlignmentDirectional.topStart),
SelectOption(label: 'topCenter', value: AlignmentDirectional.topCenter),
SelectOption(label: 'topEnd', value: AlignmentDirectional.topEnd),
SelectOption(label: 'centerStart', value: AlignmentDirectional.centerStart),
SelectOption(label: 'center', value: AlignmentDirectional.center),
SelectOption(label: 'centerEnd', value: AlignmentDirectional.centerEnd),
SelectOption(label: 'bottomStart', value: AlignmentDirectional.bottomStart),
SelectOption(label: 'bottomCenter', value: AlignmentDirectional.bottomCenter),
SelectOption(label: 'bottomEnd', value: AlignmentDirectional.bottomEnd),
];
TextDirection textDirectionValue = TextDirection.ltr;
List<SelectOption> textDirectionList = [
SelectOption(label: 'ltr', value: TextDirection.ltr),
SelectOption(label: 'rtl', value: TextDirection.rtl),
];
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Stack 布局')),
body: Scaffold(
appBar: PreferredSize(
preferredSize: const Size.fromHeight(50),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
flex: 1,
child: SelectWidget(
title: 'AlignmentDirectional',
options: alignmentList,
onChange: (SelectOption selectOption) {
setState(() {
alignmentValue = selectOption.value as AlignmentDirectional;
});
},
),
),
Expanded(
flex: 1,
child: SelectWidget(
title: 'TextDirection',
options: textDirectionList,
onChange: (SelectOption selectOption) {
setState(() {
textDirectionValue = selectOption.value as TextDirection;
});
},
),
),
],
),
),
body: Container(
width: double.infinity,
height: double.infinity,
color: Colors.grey,
child: Stack(
alignment: alignmentValue,
textDirection: textDirectionValue,
children: [
Container(width: 250, height: 250, color: Colors.red),
Container(width: 200, height: 200, color: Colors.green),
Container(width: 150, height: 150, color: Colors.blue),
Container(width: 100, height: 100, color: Colors.black),
],
),
),
),
);
}
}
Positioned布局
import 'package:flutter/material.dart';
class PositionedPage extends StatefulWidget {
const PositionedPage({super.key});
State<PositionedPage> createState() => _PositionedPage();
}
class _PositionedPage extends State<PositionedPage> {
Widget build(BuildContext context) {
// 屏幕宽度
double screenWidth = MediaQuery
.of(context)
.size
.width;
// 屏幕高度
double screenHeight = MediaQuery
.of(context)
.size
.height;
// 通知栏高度
double noticeHeight = MediaQuery
.of(context)
.padding
.top;
// 屏幕中心
double centerX = screenWidth / 2;
double centerY = (screenHeight - noticeHeight - kToolbarHeight - kBottomNavigationBarHeight) /
2;
return Scaffold(
appBar: AppBar(title: const Text('Positioned 布局')),
body: Container(
width: double.infinity,
height: double.infinity,
color: Colors.grey,
child: Stack(
children: [
// 中
Positioned(
top: centerY - 50,
left: centerX - 50,
child: Container(width: 100, height: 100, color: Colors.orange),
),
// 左上
Positioned(
top: 10,
left: 10,
child: Container(
width: 120,
height: 120,
color: Colors.red,
child: Stack(
children: [
Positioned(top: 20,
left: 20,
child: Container(width: 50, height: 50, color: Colors.black)),
],
),
),
),
// 右上
Positioned(
top: 10,
right: 10,
child: Container(
width: 120,
height: 120,
color: Colors.green,
child: Stack(
children: [
Positioned(top: 20,
right: 20,
child: Container(width: 50, height: 50, color: Colors.blue)),
],
),
),
),
// 左下
Positioned(
bottom: 10,
left: 10,
child: Container(
width: 120,
height: 120,
color: Colors.blue,
child: Stack(
children: [
Positioned(bottom: 20,
left: 20,
child: Container(width: 50, height: 50, color: Colors.green)),
],
),
),
),
// 右下
Positioned(
bottom: 10,
right: 10,
child: Container(
width: 120,
height: 120,
color: Colors.black,
child: Stack(
children: [
Positioned(bottom: 20,
right: 20,
child: Container(width: 50, height: 50, color: Colors.red)),
],
),
),
),
],
),
),
bottomNavigationBar: BottomNavigationBar(
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'HOME'),
BottomNavigationBarItem(icon: Icon(Icons.book), label: 'BOOK'),
],
),
);
}
}
路由组件
路由组件
import 'package:flutter/material.dart';
import 'package:flutter_app/views/RowColumnPage.dart';
import 'package:flutter_app/views/StackPage.dart';
import 'package:flutter_app/views/ScreenSizePage.dart';
import 'package:flutter_app/views/PositionedPage.dart';
class MenuItem {
final String title;
final Widget widget;
MenuItem({required this.title, required this.widget});
}
class RouterWidget extends StatelessWidget {
const RouterWidget({super.key});
static List<MenuItem> list = <MenuItem>[
MenuItem(title: "Row、Column 布局", widget: const RowColumnPage()),
MenuItem(title: "Stack 布局", widget: const StackPage()),
MenuItem(title: "界面尺寸", widget: const ScreenSizePage()),
MenuItem(title: "Positioned 布局", widget: const PositionedPage()),
];
Widget build(BuildContext context) {
return ListView.separated(
itemCount: list.length,
separatorBuilder: (BuildContext context, int index) => const Divider(height: 1),
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(list[index].title),
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) => list[index].widget));
},
);
},
);
}
}
入口组件
import 'package:flutter/material.dart';
import 'package:flutter_app/components/router_widget.dart';
void main() {
runApp(const App());
}
class App extends StatefulWidget {
const App({super.key});
State<App> createState() => _AppState();
}
class _AppState extends State<App> {
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false, // 移除右上角DEBUG标识
home: Scaffold(
appBar: AppBar(title: const Text("目录")),
body: const RouterWidget(),
),
);
}
}