flutter的标准APP的leading只能容纳一个图标按钮,这种方式适合手机APP这种小而窄的屏幕。对于windows大屏幕程序并非很合适。本代码模拟实现APPBAR,中间为标题文字,左右侧可以分别容纳多个菜单和ICON工具图标,是一个非常适合中小功能的windows程序的基本菜单和工具栏界面框架。
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Color _mainTextColor = Colors.black;
void _changeTextColor(Color color) {
setState(() {
_mainTextColor = color;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: CustomAppBar(
onColorChange: _changeTextColor,
),
body: Center(
child: Text(
'主窗口内容',
style: TextStyle(color: _mainTextColor, fontSize: 24),
),
),
),
);
}
}
class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
final Function(Color) onColorChange;
static const double appBarHeight = 56.0;
CustomAppBar({required this.onColorChange});
@override
Widget build(BuildContext context) {
// 计算中间区域文本的尺寸
final TextPainter textPainter = TextPainter(
text: TextSpan(text: '模拟APPBAR', style: TextStyle(fontSize: 18)),
textDirection: TextDirection.ltr,
)..layout();
final Size textSize = textPainter.size;
// 中间区域的大小(文本大小加上边距)
final double middleWidth = textSize.width + 20; // 20是边距
// 获取屏幕宽度
final double screenWidth = MediaQuery.of(context).size.width;
// 计算左右两侧区域的宽度
final double sideWidth = (screenWidth - middleWidth) / 2;
return Container(
height: appBarHeight,
color: Colors.blue,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
// 左侧区域
Container(
width: sideWidth,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: List.generate(3, (index) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 5.0),
child: PopupMenuButton<String>(
onSelected: (String value) {
switch (value) {
case '选项1':
onColorChange(Colors.red);
break;
case '选项2':
onColorChange(Colors.green);
break;
// 可以根据需要添加更多的选项和颜色
}
},
itemBuilder: (context) => [
PopupMenuItem<String>(
value: '选项1',
child: Text('选项1'),
),
PopupMenuItem<String>(
value: '选项2',
child: Text('选项2'),
),
],
child: Text('菜单$index'),
),
);
}),
),
),
// 中间区域
Container(
width: middleWidth,
alignment: Alignment.center,
child: Text(
'模拟APPBAR',
style: TextStyle(fontSize: 18.0, color: Colors.white),
),
),
// 右侧区域
Container(
width: sideWidth,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
IconButton(
icon: Icon(Icons.settings, color: Colors.white),
onPressed: () => onColorChange(Colors.purple),
tooltip: '设置',
),
IconButton(
icon: Icon(Icons.help, color: Colors.white),
onPressed: () => onColorChange(Colors.orange),
tooltip: '帮助',
),
],
),
),
],
),
);
}
@override
Size get preferredSize => Size.fromHeight(appBarHeight);
}
以下是对这段代码的分析:
一、整体结构
这段代码是一个使用 Flutter 框架构建的应用程序。主要包括一个带有自定义 AppBar 的页面,页面中央有一段文本,并且可以通过 AppBar 上的菜单和按钮来改变文本的颜色。
二、主要部分分析
main函数
void main() { runApp(MyApp()); }:这是应用程序的入口点,调用runApp函数启动应用,并传入一个MyApp实例。
MyApp类
继承自StatefulWidget,用于创建有状态的小部件。
_MyAppState createState() => _MyAppState();:创建与之关联的状态类。
_MyAppState类
维护一个Color类型的变量_mainTextColor,用于存储文本的颜色。
_changeTextColor方法:
用于响应颜色变化的回调,通过调用setState来触发小部件的重新构建。
build方法:
构建应用的主要界面,包括使用MaterialApp包裹整个应用,其中home属性设置为一个Scaffold,包含一个自定义的AppBar和页面主体的Center小部件,中心小部件是一段文本,其颜色由_mainTextColor决定。
CustomAppBar类
继承自StatelessWidget并实现PreferredSizeWidget接口,用于创建自定义的 AppBar。
包含一个Function(Color)类型的回调函数onColorChange,用于将颜色变化传递给父小部件。
appBarHeight常量定义了 AppBar 的高度。
build方法:
构建自定义 AppBar 的布局,通过计算屏幕宽度和中间文本的尺寸,将 AppBar 分为左侧、中间和右侧三个区域。
左侧区域是一系列带有弹出菜单的PopupMenuButton,每个菜单选项被选中时会调用onColorChange回调函数改变文本颜色。
中间区域显示固定文本 “模拟 APPBAR”。
右侧区域是两个带有图标按钮的IconButton,点击时也会调用onColorChange回调函数改变文本颜色。
get preferredSize方法:
返回自定义 AppBar 的尺寸。
三、功能总结
这个应用程序实现了一个具有自定义 AppBar 的界面,用户可以通过 AppBar 上的菜单和按钮来选择不同的颜色,从而改变页面中央文本的颜色。这种设计提供了一种交互方式,让用户可以根据自己的喜好定制界面的外观。