flutter windows模拟APPBAR

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 上的菜单和按钮来选择不同的颜色,从而改变页面中央文本的颜色。这种设计提供了一种交互方式,让用户可以根据自己的喜好定制界面的外观。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值