Flutter Scaffold 页面结构

Material是一套设计风格,提供了大量的小部件,这里用Material风格搭建一个常见的应用页面结构。

创建Material应用

import 'package:flutter/material.dart';class App extends StatelessWidget {Widget build(BuildContext context) {return MaterialApp(debugShowCheckedModeBanner: false, // 关闭debug条幅home: Center(child: Text("首页"),),);}
}

这里实例化的MaterialApp,而不是一般的Center Widget。

使用图表 Icon

import 'package:flutter/material.dart';class App extends StatelessWidget {Widget build(BuildContext context) {return MaterialApp(debugShowCheckedModeBanner: false, // 关闭debug条幅home: Center(child: Icon(Icons.star,color: Colors.amber,size: 128,),),);}
}

这里用到了Icon
所有Icons:https://fonts.google.com/icons
1

使用按钮 ElevatedButton

Flutter 提供了多种按钮小部件,这里ElevatedButton以为例。

import 'package:flutter/material.dart';class App extends StatelessWidget {Widget build(BuildContext context) {return MaterialApp(debugShowCheckedModeBanner: false, // 关闭debug条幅home: Center(child: ElevatedButton(onPressed: () {print("点击了按钮!");},child: Text("一个按钮"))),);}
}

1

切换主题

定义两个主题样式

在app/themes/app_theme.dart下定义两个主题样式:一个浅色,一个深色。

import 'package:flutter/material.dart';class AppTheme {static ThemeData light = ThemeData(primaryColor: Colors.deepPurpleAccent,colorScheme: ColorScheme.light(primary: Colors.deepPurpleAccent,secondary: Colors.amber,));static ThemeData dark = ThemeData(primaryColor: Colors.deepPurpleAccent,colorScheme: ColorScheme.dark(primary: Colors.cyan,secondary: Colors.amber,));
}

调用主题样式

用MaterialApp的theme和darkTheme分别调用浅色和深色主题样式。

import 'package:flutter/material.dart';
import 'package:package_name/app/themes/app_theme.dart';class App extends StatelessWidget {Widget build(BuildContext context) {return MaterialApp(debugShowCheckedModeBanner: false, // 关闭debug条幅theme: AppTheme.light,darkTheme: AppTheme.dark,home: Center(child: ElevatedButton(onPressed: () {print("点击了按钮!");},child: Text("一个按钮"))),);}
}

在IOS的设置-开发者里设置深色外观:
1
1

Scaffold 页面结构

使用Scaffold小部件可以得到一个Material风格的页面结构,可以设置页面头部工具栏、页面主体、页面底部的导航栏、侧边抽屉、底部侧板、浮动按钮等。

import 'package:flutter/material.dart';class App extends StatelessWidget {Widget build(BuildContext context) {return MaterialApp(debugShowCheckedModeBanner: false,home: DefaultTabController(// 设置默认Tab控制器length: 2,child: Scaffold(backgroundColor: Colors.amber,// 页面主体body: TabBarView(children: [Icon(Icons.explore_outlined,size: 128,color: Colors.black12,),Icon(Icons.local_fire_department,size: 128,color: Colors.black12,),]),appBar: AppBar(title: Text("页面标题"),leading: IconButton(onPressed: () {print("这是导航菜单");},icon: Icon(Icons.menu)),actions: [IconButton(onPressed: () {print("这是Action位置");},icon: Icon(Icons.more_horiz))],bottom: TabBar(tabs: [// 设置标签栏Tab(text: 'Tab1',),Tab(text: 'Tab2',)]),),bottomNavigationBar: BottomNavigationBar(items: [BottomNavigationBarItem(icon: Icon(Icons.explore_outlined), label: "发现"),BottomNavigationBarItem(icon: Icon(Icons.add_a_photo_outlined), label: "添加"),BottomNavigationBarItem(icon: Icon(Icons.account_circle_outlined), label: "用户")]),),));}
}

Scaffold
如果是VSCode编辑器,在StatelessWidget上按快捷键Ctrl/Command+.,执行Convert to StatefulWidget命令,可以把无状态小部件转换成有状态小部件。

import 'package:flutter/material.dart';class App extends StatefulWidget {State<App> createState() => _AppState();
}class _AppState extends State<App> {Widget build(BuildContext context) {return MaterialApp(}
}

有状态小部件多出一个_AppState状态类,用于管理状态,通过createState、setState来创建和设置状态。

激活底部导航

import 'package:flutter/material.dart';class App extends StatefulWidget {State<App> createState() => _AppState();
}class _AppState extends State<App> {int currentAppBottomNavigationBarItem = 0;void onTabAppBottomNavigationBarItem(int index) {setState(() {currentAppBottomNavigationBarItem = index;});}Widget build(BuildContext context) {return MaterialApp(debugShowCheckedModeBanner: false,home: DefaultTabController(// 设置默认Tab控制器length: 2,child: Scaffold(backgroundColor: Colors.amber,// 页面主体body: TabBarView(children: [Icon(Icons.explore_outlined,size: 128,color: Colors.black12,),Icon(Icons.local_fire_department,size: 128,color: Colors.black12,),]),appBar: AppBar(title: Text("页面标题"),leading: IconButton(onPressed: () {print("这是导航菜单");},icon: Icon(Icons.menu)),actions: [IconButton(onPressed: () {print("这是Action位置");},icon: Icon(Icons.more_horiz))],bottom: TabBar(tabs: [// 设置标签栏Tab(text: 'Tab1',),Tab(text: 'Tab2',)]),),bottomNavigationBar: BottomNavigationBar(currentIndex: currentAppBottomNavigationBarItem,onTap: onTabAppBottomNavigationBarItem,items: [BottomNavigationBarItem(icon: Icon(Icons.explore_outlined), label: "发现"),BottomNavigationBarItem(icon: Icon(Icons.add_a_photo_outlined), label: "添加"),BottomNavigationBarItem(icon: Icon(Icons.account_circle_outlined), label: "用户")]),),));}
}

1

点击底部导航,切换显示小部件

  final pageMain = [TabBarView(children: [Icon(Icons.explore_outlined,size: 128,color: Colors.black12,),Icon(Icons.local_fire_department,size: 128,color: Colors.black12,),]),Center(child: Icon(Icons.add_a_photo_outlined,size: 128,color: Colors.black12,),),Center(child: Icon(Icons.account_circle_outlined,size: 128,color: Colors.black12,),)];

首先定义三个小部件列表,然后在body里按照索引来调用。

body: pageMain.elementAt(currentAppBottomNavigationBarItem),

1

动态显示或隐藏AppBar

用showAppBar来决定是否显示appBar。

class _AppState extends State<App> {// 是否显示应用栏bool showAppBar = true;int currentAppBottomNavigationBarItem = 0;void onTabAppBottomNavigationBarItem(int index) {setState(() {currentAppBottomNavigationBarItem = index;// 第一个显示,其他不显示showAppBar = index == 0;}
appBar: showAppBar ? AppBar(...) : null,

appBar设置为null,就是隐藏。

FloatingActionButton 漂浮动作按钮

floatingActionButton: FloatingActionButton(
onPressed: () {print('这是漂浮动作按钮。');
},
child: Icon(Icons.share_outlined),
backgroundColor: Colors.black,
foregroundColor: Colors.white,
)

用Scaffold的floatingActionButton参数,可以设置漂浮动作按钮。

定义部件

上面的小部件都是放在一起,我们还可以把一些把页面的部分小部件单独放到一个文件里,这里以appBar为例:

app_page_header.dart

import 'package:flutter/material.dart';class AppPageHeader extends StatelessWidget implements PreferredSizeWidget {final Size preferredSize = Size.fromHeight(100);Widget build(BuildContext context) {return AppBar(title: Text("页面标题"),leading: IconButton(onPressed: () {print("这是导航菜单");},icon: Icon(Icons.menu)),actions: [IconButton(onPressed: () {print("这是Action位置");},icon: Icon(Icons.more_horiz))],bottom: TabBar(tabs: [// 设置标签栏Tab(text: 'Tab1',),Tab(text: 'Tab2',)]),);}
}

这里单独定义了一个AppPageHeader的类,作为appBar,然后我们就可以调用它了。

import 'package:package_name/app/components/app_page_header.dart';appBar: showAppBar ? AppPageHeader() : null,

BottomSheet 底部面板

这里点击浮动按钮显示底部面板,把浮动按钮单独封装成了一个单独的文件app_floating_action_button.dart:

import 'package:flutter/material.dart';class AppFloatingActionButton extends StatelessWidget {Widget build(BuildContext context) {return FloatingActionButton(onPressed: () {print('这是漂浮动作按钮。');showBottomSheet(context: context,builder: (BuildContext context) {return SizedBox.expand(child: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,mainAxisSize: MainAxisSize.min,children: <Widget>[const Text('漂浮动作按钮'),ElevatedButton(child: const Text('关闭'),onPressed: () => Navigator.pop(context),),],),),);},);},child: Icon(Icons.share_outlined),backgroundColor: Colors.black,foregroundColor: Colors.white,);}
}

调用:

floatingActionButton: AppFloatingActionButton(),

1

边栏抽屉

import 'package:flutter/material.dart';class AppPageAside extends StatelessWidget {Widget build(BuildContext context) {return Drawer(child: Center(child: Text("边栏抽屉"),),);}
}

在Scaffold函数里用drawer参数调用:

drawer: AppPageAside(),

1

AppBar leading 位置显示抽屉

onPressed: () {Scaffold.of(context).openDrawer();
},

设置边栏抽屉显示的内容

import 'package:flutter/material.dart';class AppPageAside extends StatelessWidget {Widget build(BuildContext context) {return Drawer(child: Center(child: ListView(padding: EdgeInsets.zero,children: [UserAccountsDrawerHeader(accountName: Text("姓名"), accountEmail: Text("abc@domain.com")),ListTile(title: Text("评论",textAlign: TextAlign.right,),trailing: Icon(Icons.comment_outlined),),ListTile(title: Text("账户",textAlign: TextAlign.right,),trailing: Icon(Icons.account_box_outlined),),ListTile(title: Text("退出",textAlign: TextAlign.right,),trailing: Icon(Icons.logout_outlined),),],),),);}
}

1

弹出菜单

import 'package:flutter/material.dart';class AppPageHeaderActionsMore extends StatelessWidget {Widget build(BuildContext context) {return PopupMenuButton(itemBuilder: (context) => [PopupMenuItem(value: 'stack',child: Icon(Icons.view_agenda_outlined,color: Colors.black12,),),PopupMenuItem(value: 'stack',child: Icon(Icons.dashboard_outlined,color: Colors.black12,),),],icon: Icon(Icons.more_horiz),offset: Offset(0, 50),onCanceled: () {print("弹出菜单按钮");},onSelected: (value) {print("弹出菜单按钮的值是 $value");},);}
}
AppBar(
......actions: [AppPageHeaderActionsMore(),]
......

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/68965.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】string类(上):string类的常用接口介绍

文章目录 前言一、C中设计string类的意义二、string类的常用接口说明1. string类对象的常见构造2. string类对象的容量操作2.1 size、capacity 和 empty的使用2.2 clear的使用2.3 reserve的使用2.4 resize的使用 3. string类对象的访问及遍历操作3.1 下标[ ] 和 at3.2 迭代器it…

一文讲解Java中的ArrayList和LinkedList

ArrayList和LinkedList有什么区别&#xff1f; ArrayList 是基于数组实现的&#xff0c;LinkedList 是基于链表实现的。 二者用途有什么不同&#xff1f; 多数情况下&#xff0c;ArrayList更利于查找&#xff0c;LinkedList更利于增删 由于 ArrayList 是基于数组实现的&#…

STM32 DMA+AD多通道

接线图 代码配置 ADC单次扫描DMA单次转运模式 uint16_t AD_Value[4]; //DMAAD多通道 void DMA_Config(void) {//定义结构体变量 GPIO_InitTypeDef GPIO_InitStructure;//定义GPIO结构体变量 ADC_InitTypeDef ADC_InitStructure; //定义ADC结构体变量 DMA_InitTypeDef DMA_In…

浅谈《图解HTTP》

感悟 滑至尾页的那一刻&#xff0c;内心突兀的涌来一阵畅快的感觉。如果说从前对互联网只是懵懵懂懂&#xff0c;但此刻却觉得她是如此清晰而可爱的呈现在哪里。 介绍中说&#xff0c;《图解HTTP》适合作为第一本网络协议书。确实&#xff0c;它就像一座桥梁&#xff0c;连接…

Alibaba开发规范_异常日志之日志规约:最佳实践与常见陷阱

文章目录 引言1. 使用SLF4J日志门面规则解释代码示例正例反例 2. 日志文件的保存时间规则解释 3. 日志文件的命名规范规则解释代码示例正例反例 4. 使用占位符进行日志拼接规则解释代码示例正例反例 5. 日志级别的开关判断规则解释代码示例正例反例 6. 避免重复打印日志规则解释…

自动化软件测试的基本流程

一、自动化测试的准备 1.1 了解测试系统 首先对于需要测试的系统我们需要按照软件需求说明书明确软件功能。这里以智慧养老系统作为案例进行测试&#xff0c;先让我们看看该系统的登录界面和用户管理界面。 登录界面&#xff1a; 登录成功默认界面&#xff1a; 用户管理界面…

Windows电脑本地部署运行DeepSeek R1大模型(基于Ollama和Chatbox)

文章目录 一、环境准备二、安装Ollama2.1 访问Ollama官方网站2.2 下载适用于Windows的安装包2.3 安装Ollama安装包2.4 指定Ollama安装目录2.5 指定Ollama的大模型的存储目录 三、选择DeepSeek R1模型四、下载并运行DeepSeek R1模型五、常见问题解答六、使用Chatbox进行交互6.1 …

计算机网络中常见高危端口有哪些?如何封禁高危端口?

保障网络安全&#xff0c;从封禁高危端口开始&#xff01; 在计算机网络中&#xff0c;端口是设备与外界通信的“大门”&#xff0c;但某些端口因常被黑客利用而成为高危入口。封禁这些端口是防御网络攻击的关键一步。本文将详解 10个常见高危端口&#xff0c;并提供多平台封禁…

CommonJS

CommonJS 是由 JavaScript 社区于 2oo9 年提出的包含模块、文件、IO、控制台在内的一系列标准。Node.js 的实现中采用了 CommonJS 标准的一部分&#xff0c;并在其基础上进行了一些调整。我们所说的 CommonJS 模块和 Node.js 中的实现并不完全一样&#xff0c;现在一般谈到 Com…

[SAP ABAP] ABAP SQL跟踪工具

事务码ST05 操作步骤 步骤1&#xff1a;使用事务码ST05之前&#xff0c;将要检测的程序生成的页面先呈现出来&#xff0c;这里我们想看下面程序的取数操作&#xff0c;所以停留在选择界面 步骤2&#xff1a; 新建一个GUI窗口&#xff0c;输入事务码ST05&#xff0c;点击 Acti…

蓝桥杯备考:高精度算法之除法

我们除法的高精度其实也不完全是高精度&#xff0c;而是一个高精度作被除数除以一个低精度 模拟我们的小学除法 由于题目中我们的除数最大是1e9&#xff0c;当它真正是1e9的时候&#xff0c;t是有可能超过1e9的&#xff0c;所以要用long long

算法竞赛(Python)-堆栈

文章目录 一 基础知识二 题目有效的括号字符串解码 一 基础知识 堆栈&#xff08;Stack&#xff09;&#xff1a;简称为栈。一种线性表数据结构&#xff0c;是一种只允许在表的一端进行插入和删除操作的线性表。   我们把栈中允许插入和删除的一端称为 「栈顶&#xff08;top…

SpringBoot 中的测试jar包knife4j(实现效果非常简单)

1、效果图 非常快的可以看见你实现的接口 路径http://localhost:8080/doc.html#/home 端口必须是自己的 2、实现效果 2.1、导入jar包 <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-openapi3-jakarta-spring-boot-star…

16.1.STM32F407ZGT6-CAN基础概念

参考&#xff1a; https://blog.csdn.net/sunlight_vip/article/details/128639144 前言&#xff1a; 学习总结CAN的知识点&#xff1a; 1.can是什么&#xff0c;历史由来和背景 2.can的物理层&#xff0c;链路层 3.初始化的流程和关键点 4.波特率怎么设置 5.can id怎么过滤 6…

Linux环境下的Java项目部署技巧:Nginx 详解

Nginx 的启动 Nginx 启动会生成 2 个进程&#xff1a;主进程与守护进程 主进程&#xff1a;常用于提供反向代理服务。特点&#xff1a;占内存大守护进程&#xff1a;防止主进程以外关闭。特点&#xff1a;占内存小 Nginx 启动需要占用 80 端口: 当 Ngnix 启动失败时&#xff0…

【Pytorch和Keras】使用transformer库进行图像分类

目录 一、环境准备二、基于Pytorch的预训练模型1、准备数据集2、加载预训练模型3、 使用pytorch进行模型构建 三、基于keras的预训练模型四、模型测试五、参考 现在大多数的模型都会上传到huggface平台进行统一的管理&#xff0c;transformer库能关联到huggface中对应的模型&am…

relational DB与NoSQL DB有什么区别?该如何选型?

Relational Database(关系型数据库,简称RDB)与NoSQL Database(非关系型数据库)是两类常见的数据库类型。它们在设计理念、数据存储方式、性能优化、扩展性等方面有许多差异。下面我们将会详细分析它们的区别,以及如何根据应用场景进行选型。 一、数据模型的区别 关系型…

Flutter常用Widget小部件

小部件Widget是一个类&#xff0c;按照继承方式&#xff0c;分为无状态的StatelessWidget和有状态的StatefulWidget。 这里先创建一个简单的无状态的Text小部件。 Text文本Widget 文件&#xff1a;lib/app/app.dart。 import package:flutter/material.dart;class App exte…

智能小区物业管理系统推动数字化转型与提升用户居住体验

内容概要 在当今快速发展的社会中&#xff0c;智能小区物业管理系统的出现正在改变传统的物业管理方式。这种系统不仅仅是一种工具&#xff0c;更是一种推动数字化转型的重要力量。它通过高效的技术手段&#xff0c;将物业管理与用户居住体验紧密结合&#xff0c;无疑为社区带…

给AI加知识库

1、加载 Document Loader文档加载器 在 langchain_community. document_loaders 里有很多种文档加载器 from langchain_community. document_loaders import *** 1、纯文本加载器&#xff1a;TextLoader&#xff0c;纯文本&#xff08;不包含任何粗体、下划线、字号格式&am…