学习Flutter的第二天(Scaffold)
2023-04-19 本文已影响0人
囧rg
2. Scaffold
2.1 AppBar
名称 | 功能 |
---|---|
leading | 标题前置控件。在首页通常显示应用程序的Logo,其它页面通常显示为返回按钮 |
title | 页面标题。通常显示当前页面的标题文字,可以放组件 |
actions | 标题后置控件。通常使用IconButton来表示,可以放按钮组 |
bottom | 底部控件。通常用tabBar来表示放置Tab标签栏 |
backgroundColor | 导航背景颜色 |
iconTheme | 图标样式 |
textTheme | 文字样式 |
centerTitle | 标题是否居中显示 |
elevation | 值是0.0 就是没有阴影 |
import 'package:flutter/material.dart';
import './pages/tabs.dart';
void main() {
runApp(const MyApp());
}
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(
// 背景颜色
backgroundColor: Colors.red,
// 左侧按钮
leading: IconButton(
onPressed: () {
print("左侧按钮");
},
icon: const Icon(Icons.menu)),
// 右边按钮
actions: [
IconButton(
onPressed: () {
print("setting");
},
icon: const Icon(Icons.settings)),
IconButton(
onPressed: () {
print("more");
},
icon: const Icon(Icons.more))
],
title: const Text("Demo1"),
),
body: const Text("sss"),
),
);
}
}
2.2 TabBar
TabBar是作为AppBar的一部分存在。参考文档 中提供了两种实现顶部TabLayout的方法,两者效果是一样的,但第二种功能更为丰富。具体为 TabBar + TabBarView
两个weight结合。
名称 | 功能 |
---|---|
tabs | 标签组 |
controller | 标签控制器 |
isScrollable | 标签组是否可以滚动 |
indicatorColor | 指示器的颜色 |
indicatorWeight | 指示器高度 |
indicatorPadding | 指示器的内边距 |
indicator | 指标器装饰 |
indicatorSize | 指示器的大小 |
labelColor | 标签的颜色 |
labelStyle | 标签的样式 |
labelPadding | 标签的内边距 |
unselectedLabelColor | 选中标签的颜色 |
unselectedLabelStyle | 选中标签的样式 |
2.2.1 DefaultTabController
使用 DefaultTabController
作为最外层控制器,联调 TabBar + TabBarView
,这种方式简单方便,但致命缺点是拿不到当前选中tab的index。
class FirstPage extends StatefulWidget {
FirstPage({Key key, this.title}) : super(key: key);
final String title;
@override
State<StatefulWidget> createState() => _FirstPageState();
}
/// DefaultTabController (TabBar + TabBarView) 使用 (内部还是TabController实现)
class _FirstPageState extends State<FirstPage> {
final List<Tab> myTabs = <Tab>[
Tab(text: '全部订单'),
Tab(text: '已完成'),
Tab(text: '未完成')
];
@override
Widget build(BuildContext context) {
// 1. 使用 DefaultTabController 作为外层控制器
return DefaultTabController(
length: myTabs.length,// 定义tab数量
child: Scaffold(
appBar: AppBar(
title: Text('FirstPage'),
// 2. 使用 TabBar
bottom: TabBar(
tabs: myTabs // 定义TabWeight,若数量和定义不一致会报错
),
),
// 3. 使用 TabBarView
body: TabBarView(
children: <Widget>[
/// 全部订单
Center(child: Text('全部订单')),
/// 已完成订单
Center(child: Text('已完成')),
/// 未完成订单
Center(child: Text('未完成'))
]),
),
);
}
}
2.2.2 TabController
实现SingleTickerProviderStateMixin
,重写初始化和注销方法,利用控制器TabController
管理和更多操作,其实第一种方法内部也是由TabController实现的。
// 1. 实现 SingleTickerProviderStateMixin
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
TabController _tabController;
static const List<Tab> _homeTopTabList = <Tab>[
Tab(text: '音乐', icon: Icon(Icons.music_note)),
Tab(text: '体育', icon: Icon(Icons.directions_run)),
Tab(text: '天气', icon: Icon(Icons.cloud_queue)),
Tab(text: '科技', icon: Icon(Icons.toys))
];
// 2. 初始化状态
@override
void initState() {
super.initState();
// TabController的滚动事件会触发一次监听, 点击事件会触发两次监听(一次是正常触发,一次是tab的动画触发)
_tabController = TabController(length: _homeTopTabList.length, vsync: this);
// 添加监听获取tab选中下标
_tabController.addListener((){
_currentTopTabIndex = _tabController.index;
});
}
// 3. 注销状态
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
// 4. 添加TabBar
bottom: TabBar(
tabs: _homeTopTabList,
controller: _tabController
),
),
// 5. 添加TabBarView
body: TabBarView(
controller: _tabController,
children: <Widget>[
_tabMusic(context),
_tabSport(context),
_tabSport(context),
_tabSport(context)
],
),
);
}
注:关于TabController 的监听有个坑 踩坑TabBar之TabController.addListener
2.1 bottomNavigationBar
BottomNavigationBar
和 BottomNavigationBarItem
配合来共同展示Flutter里面的底部状态栏,底部状态栏是在移动端很重要的控件。
名称 | 功能 |
---|---|
items | 底部导航按钮集合 |
iconSize | icon |
currentIndex | 默认选中第几个 |
onTap | 选中变化回调函数 |
fixedColor | 选中的颜色 |
type | BottomNavigationBarType.fixed 或 BottomNavigationBarType.shifting |
下面代码实现:点击底部的导航按钮,显示不同的页面
main.dart
import 'package:flutter/material.dart';
import './pages/tabs.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Flutter Demo",
theme: ThemeData(primarySwatch: Colors.blue),
home: const Tabs(),
);
}
}
tabs.dart
import 'package:flutter/material.dart';
import './tabs/home.dart';
import './tabs/category.dart';
import './tabs/me.dart';
class Tabs extends StatefulWidget {
const Tabs({super.key});
@override
State<Tabs> createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
final List<Widget> _pages = const [Home(), Category(), Me()];
int _currentIndex = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Demo1"),
),
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (index) {
setState(() {
_currentIndex = index;
});
},
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: "首页"),
BottomNavigationBarItem(icon: Icon(Icons.category), label: "分类"),
BottomNavigationBarItem(icon: Icon(Icons.person), label: "我"),
],
// 底部有4个,或者4个以上的时候才生效
type: BottomNavigationBarType.fixed,
),
);
}
}
category.dart 、home.dart 、 me.dart
import 'package:flutter/material.dart';
class Category extends StatefulWidget {
const Category({super.key});
@override
State<Category> createState() => _CategoryState();
}
class _CategoryState extends State<Category> {
@override
Widget build(BuildContext context) {
return const Center(
child: Text("分类"),
);
}
}
2.2 floatingActionButton
用来实现悬浮按钮效果的
class ScffoldHomePage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return ScffoldHomePageState();
}
}
class ScffoldHomePageState extends State<ScffoldHomePage> {
///当前选中的页面
num index =0;
@override
Widget build(BuildContext context) {
///使用 Scaffold 组件来构建应用的基本页面
/// 页面的架构
return Scaffold(
///定义页面的标题
appBar: AppBar(
title: Text("这里是首页"),
),
///定义的页面的主体内容
body:pageWidgetList[index],
///定义的悬浮按钮
floatingActionButton: FloatingActionButton(
child: Text("++"),
///点击响应事
onPressed: () {
print("点击了 FloatingActionButton");
},
///长按提示
tooltip: "点击了 tooltip s ",
///设置悬浮按钮的背景
backgroundColor: Colors.red,
///获取焦点时显示的颜色
focusColor: Colors.green,
///鼠标悬浮在按钮上时显示的颜色
hoverColor: Colors.yellow,
///水波纹颜色
splashColor: Colors.deepPurple,
///定义前景色 主要影响文字的颜色
foregroundColor: Colors.black,
///配制阴影高度 未点击时
elevation: 0.0,
///配制阴影高度 点击时
highlightElevation: 20.0,
),
///用来控制 FloatingActionButton 的位置
///FloatingActionButtonLocation.endFloat 默认使用 浮动右下角
///FloatingActionButtonLocation.endDocked 右下角
///FloatingActionButtonLocation.endTop 右上角
///FloatingActionButtonLocation.startTop 左上角
///FloatingActionButtonLocation.centerFloat 底部中间浮动
///FloatingActionButtonLocation.centerDocked 底部中间不浮动
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
);
}
}
2.3 drawer
抽屉组件
import "package:flutter/material.dart";
class CategoryPage extends StatefulWidget {
CategoryPage({Key key}) : super(key: key);
_CategoryPageState createState() => _CategoryPageState();
}
class _CategoryPageState extends State<CategoryPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Flutter App"),
),
// 左侧抽屉
drawer: Drawer(
child: Text('左侧抽屉'),
),
// 右侧抽屉
endDrawer: Drawer(
child: Text('右侧抽屉'),
),
);
}
}