目录
- WillPopScope(返回事件拦截器)
- InheritedWidget(数据传递与共享)
- Theme (主题控制)
WillPopScope(返回事件拦截器)
可防止误触情况的发生,也可监听返回按钮点击事件
const WillPopScope({
Key key,
@required this.child,
@required this.onWillPop,
}) : assert(child != null),
super(key: key);
- onWillPop:返回事件回调函数,点击返回按钮时调用。此回调方法返回 true 时退出,返回 false 时不会退出
- child:子元素
import 'package:flutter/material.dart';
/**
* @des WillPopScope Test
* @author liyongli 20190514
* */
class WillPopScopeTest extends StatefulWidget{
@override
State createState() {
return new _WillPopScopeTestState();
}
}
/**
* @des WillPopScope Test State
* @author liyongli 20190514
* */
class _WillPopScopeTestState extends State{
DateTime _lastPress;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("WillPopScope"),
),
body: WillPopScope(
child: Container(
alignment: Alignment.center,
child: Text("back 两次退出(2秒内)"),
),
onWillPop: () async{
if(null == _lastPress || DateTime.now().difference(_lastPress) > Duration(seconds: 2)){
_lastPress = DateTime.now();
return false; // false = 不退出
}
return true; // true = 退出
}
),
),
);
}
}
InheritedWidget(数据传递与共享)
通过 InheritedWidget 数据可以在 Widget 树中从上向下共享与传递,组件之间也可实现跨级传递数据
const InheritedWidget({ Key key, Widget child })
: super(key: key, child: child);
构造方法非常简单,故不展开解释,重点通过以下实例演示逻辑关系与运用方法:
- InheritedWidgetTest:共享数据提供者
- InheritedChildWidgetTest:共享数据获取者
- DataChangeTest:共享数据修改者
import 'package:flutter/material.dart';
/**
* @des InheritedWidget Test(共享数据提供者)
* @author liyongli 20190514
* */
class InheritedWidgetTest extends InheritedWidget{
int data; // 被共享的数据
InheritedWidgetTest({
@required this.data,
Widget child
}):super(child:child);
// 获取共享数据
static InheritedWidgetTest getData(BuildContext con){
return con.inheritFromWidgetOfExactType(InheritedWidgetTest);
}
@override
bool updateShouldNotify(InheritedWidgetTest oldWidget) {
return oldWidget.data != data;
}
}
/**
* @des Inherited Child Widget Test(共享数据获取者)
* @author liyongli 20190514
* */
class InheritedChildWidgetTest extends StatefulWidget {
@override
State createState() {
return new _InheritedChildWidgetTest();
}
}
/**
* @des Inherited Child Widget Test State
* @author liyongli 20190514
* */
class _InheritedChildWidgetTest extends State{
@override
Widget build(BuildContext context) {
return Text(InheritedWidgetTest.getData(context).data.toString());
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
print("_InheritedChildWidgetTest didChangeDependencies");
}
}
/**
* @des Data Change Test Widget(共享数据修改者)
* @author liyongli 20190514
* */
class DataChangeTest extends StatefulWidget{
@override
State createState() {
return new _DataChangeTestState();
}
}
/**
* @des Data Change Test Widget State
* @author liyongli 20190514
* */
class _DataChangeTestState extends State{
int count = 0;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("DataChangeTest"),
),
body: Center(
child: InheritedWidgetTest(
data: count,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
InheritedChildWidgetTest(),
RaisedButton(
child: Text("$count"),
onPressed: () => setState(() => ++count),
),
],
),
),
),
),
);
}
}
Theme (主题控制)
通过 ThemeData 可以控制 Theme 视图内的组件风格,如颜色、字体、样式等,实际上也是通过 InheritedWidget 来共享与传递主题数据
const Theme({
Key key,
@required this.data,
this.isMaterialAppTheme = false,
@required this.child,
}) : assert(child != null),
assert(data != null),
super(key: key);
- data: 就是 ThemeData 以及包含的具体设置项和参数
- child: 子元素
ThemeData({
Brightness brightness, // 深色、浅色
MaterialColor primarySwatch, // 主题颜色样本,比如:
Color primaryColor, // 主色,也是导航栏背景色
Color accentColor, // 次级色,决定大多数子元素的颜色
Color dividerColor, // 分割线的颜色
ButtonThemeData buttonTheme, // 按钮的主题
Color cursorColor, // 输入框光标的颜色
String fontFamily, // 文字的字体
IconThemeData iconTheme, // Icon 的默认样式
... 等等等等,以上只是罗列了部分属性
})
import 'package:flutter/material.dart';
/**
* @des Theme Test
* @author liyongli 20190514
* */
class ThemeTest extends StatefulWidget{
@override
State createState() {
return new _ThemeTestState();
}
}
/**
* @des Theme Test State
* @author liyongli 20190514
* */
class _ThemeTestState extends State{
Color _themeColor = Colors.deepOrange;
@override
Widget build(BuildContext context) {
ThemeData themeData = Theme.of(context);
return Theme(
data: ThemeData(
primarySwatch: _themeColor,
iconTheme: IconThemeData(color: _themeColor)
),
child: Scaffold(
// 导航栏部分
appBar: AppBar(
title: Text("Theme"),
),
// 主题部分
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 使用主题 Theme 的子元素
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.accessibility_new),
Icon(Icons.airport_shuttle),
Text(" 切换")
]
),
// 在 Theme 中也可设置局部保持自己的 Theme
Theme(
data: themeData.copyWith(
iconTheme: themeData.iconTheme.copyWith(
color: Colors.black
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.accessibility_new),
Icon(Icons.airport_shuttle),
Text(" 保持")
]
),
),
],
),
// 悬浮的切换 Theme 按钮
floatingActionButton: FloatingActionButton(
onPressed: () =>
setState(() =>
_themeColor = _themeColor == Colors.deepOrange ? Colors.blue : Colors.deepOrange
),
child: Icon(Icons.zoom_out_map)
),
),
);
}
}
本篇到此完结,更多 Flutter 跨平台移动端开发 原创内容持续更新中~
期待您 关注 / 点赞 / 收藏 向着 大前端工程师 晋级!