Flutter(一)-Widget&&Context
从前端角度,快速入门Flutter
widget
和React的Component概念类似,Flutter中一切都是Widget
Widget又分为 Stateless Widget
和 Stateful Widget
也和React中有状态,无状态组件类似
语法
和React的Class语法类似,需要注意的是,每个Widget都需要写一下构造函数
class Echo extends StatelessWidget {
const Echo({
Key? key,
required this.text,
this.backgroundColor = Colors.grey, //默认为灰色
}):super(key:key);
final String text;
final Color backgroundColor;
@override
Widget build(BuildContext context) {
return Center(
child: Container(
color: backgroundColor,
child: Text(text),
),
);
}
}
这里的super(key)
是也是标准做法,调用父类(StatelessWidget )的构造函数,key和React中列表项的Key的优化作用类似
Stateless Widget
无状态Widget --> React中的无状态组件
Stateful Widget
有状态Widget --> React中的有状态组件
一个 StatefulWidget 类会对应一个 State 类
widget
,它表示与该 State 实例关联的 widget 实例,由Flutter 框架动态设置。注意,这种关联并非永久的,因为在应用生命周期中,UI树上的某一个节点的 widget 实例在重新构建时可能会变化,但State实例只会在第一次插入到树中时被创建,当在重新构建时,如果 widget 被修改了,Flutter 框架会动态设置State. widget 为新的 widget 实例。context
。StatefulWidget对应的 BuildContext,作用同StatelessWidget 的BuildContex
如何写?
一个典型有状态Widget
class DemoPage extends StatefulWidget {
@override
_DemoPage createState() => new _DemoPage();
}
class _DemoPage extends State<DemoPage> {
int _counter = 0;
@override
void initState() {
super.initState();
init();
}
void init() async {
//logger.i('init ${Uri.base}');
}
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
@override
Widget build(BuildContext) {
return Scaffold(
appBar: AppBar(
title: Text('Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
上面结构会生成一颗WidgetTree
Context
Context可能找不到React中的概念,比较抽象,可以理解为Widget的一部分,上面有上下文信息,可以用来做路由管理、访问媒体信息、状态管理
Context的应用场景
1. 导航
在 Flutter 中,BuildContext
用于管理路由和导航。每个 Widget 都有一个 Context,这个 Context 知道如何在 Widget 树中导航。
-
Navigator
API:- 使用
Navigator.of(context)
可以访问 Navigator,这是一个管理路由堆栈的对象。你可以用它来推送和弹出路由,实现页面之间的跳转。
Navigator.of(context).push( MaterialPageRoute(builder: (context) => NewPage()), );
- 弹出路由:
Navigator.of(context).pop();
- 使用
2. 显示对话框
BuildContext
也用于显示模态对话框或底部表单。
-
showDialog
:- 使用
showDialog
函数可以在当前页面上弹出一个对话框。
showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: Text('Alert'), content: Text('This is an alert message.'), actions: <Widget>[ FlatButton( child: Text('OK'), onPressed: () { Navigator.of(context).pop(); }, ), ], ); }, );
- 使用
3. 访问 Inherited Widgets
BuildContext
提供了访问继承的 Widget,例如 Theme
或 MediaQuery
的能力。
-
Theme.of(context)
:- 获取当前主题的颜色、字体样式等。
Color color = Theme.of(context).primaryColor;
-
MediaQuery.of(context)
:- 获取设备的屏幕尺寸、方向和其他媒体特性。
var size = MediaQuery.of(context).size;
4. 状态管理
在使用状态管理解决方案如 Provider 时,BuildContext
用于查找数据模型。
-
Provider.of<T>(context)
:- 从最近的 Provider 获取类型为 T 的数据。
var myModel = Provider.of<MyModel>(context);
5. 获取本地化资源
BuildContext
也用于访问本地化字符串或配置。
-
Localizations.of<T>(context, T)
:- 获取指定类型的本地化资源。
String title = Localizations.of<MyLocalizations>(context, MyLocalizations).title;
以上就是一些Context的应用场景,可以看到基本父Widget的State对象的获取方法,语法如parentWidget.of(context)
,这是Flutter语法层面上的约定:如果 StatefulWidget 的状态是希望暴露出的,应当在 StatefulWidget 中提供一个of
静态方法来获取其 State 对象,开发者便可直接通过���方法来获取
转载自:https://juejin.cn/post/7387001928209661967