每当我们在flutter创建一个新的小部件时,总会有一个与之关联的构建小部件,并且BuildContext参数由框架传递。
Widget build ( BuildContext context )
Flutter会注意,除了需要在其构造函数或函数中使用上下文参数的构建之外,不需要任何 Widget。因此,我们必须仅通过 build Widget 传递 context 参数,否则对 build函数的调用将不止一次。
这就是 Builder 类出现的地方。 Builder 类的主要函数是构建孩子并返回它。 Builder 类将上下文传递给子级,它充当自定义构建函数。
Builder 类构造函数
Builder({Key key, @required WidgetBuilder builder})
builder 参数不能为空。
该类可用的不同方法是——
- 构建(BuildContext 上下文)→ 小部件
- createElement() → StatelessElement
- debugDescribeChildren() → List
- debugFillProperties(DiagnosticPropertiesBuilder 属性) → 无效
- noSuchMethod(Invocation invocation) → 动态
- toString({DiagnosticLevel minLevel: DiagnosticLevel.info}) → 字符串
我们将使用以下示例来了解 Builder 类的函数。我们实际上制作了一个非常简单的应用程序来演示这一点。该应用程序的主屏幕有一个带有 AppBar 的简单 Scaffold,主体带有一个由 GestureDetector 制作的简单按钮。该按钮的目的是在用户单击该按钮时显示一个 SnackBar。
主要的。 dart文件如下
Dart
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Builder Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.green,
),
home: Home(),
);
}
}
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
// appbar
appBar: AppBar(
title: Text('GeeksforGeeks'),
),
// detect gesture
body: Center(
child: GestureDetector(
onTap: () {
Scaffold.of(context).showSnackBar(
new SnackBar(
content: new Text('GeeksforGeeks'),
),
);
},
// box styling
child: Container(
margin: EdgeInsets.all(18),
height: 40,
decoration: BoxDecoration(
color: Colors.blueGrey,
borderRadius: BorderRadius.circular(8),
),
child: Center(
child: Text(
'CLICK ME',
style:
TextStyle(fontWeight: FontWeight.bold, color: Colors.white),
),
),
),
),
),
);
}
}
Dart
body: Center(
child: Builder(builder: (BuildContext context) {
return GestureDetector(
onTap: () {
Scaffold.of(context).showSnackBar(
new SnackBar(
content: new Text('GeeksforGeeks'),
),
);
},
child: Container(
margin: EdgeInsets.all(18),
height: 40,
decoration: BoxDecoration(
color: Colors.blueGrey,
borderRadius: BorderRadius.circular(8),
),
child: Center(
child: Text(
'CLICK ME',
style: TextStyle(
fontWeight: FontWeight.bold, color: Colors.white),
),
),
),
);
}),
),
如果我们运行上面的程序,我们会得到以下错误——
======== Exception caught by gesture ===============================================================
Scaffold.of() called with a context that does not contain a Scaffold.
====================================================================================================
发生错误是因为我们正在构建 Scaffold 的同时调用 SnackBar 小部件(即相同的上下文被传递到 Scaffold 和 SnackBar )。正在传递的上下文不属于 Scaffold,并且 SnackBar 出现需要有一个 Scaffold。所以应用程序给出了错误。
为了纠正这个错误,我们可以用一个 Builder 小部件包装手势检测器,如下所示。在这种情况下,上下文将通过 Builder 传递给 SnackBar 小部件。 SnackBar 成为传递的 Scaffold 上下文的子级。现在,如果单击按钮它会提供所需的输出,因为 Scaffold 已经存在以供 SnackBar 出现。
Dart
body: Center(
child: Builder(builder: (BuildContext context) {
return GestureDetector(
onTap: () {
Scaffold.of(context).showSnackBar(
new SnackBar(
content: new Text('GeeksforGeeks'),
),
);
},
child: Container(
margin: EdgeInsets.all(18),
height: 40,
decoration: BoxDecoration(
color: Colors.blueGrey,
borderRadius: BorderRadius.circular(8),
),
child: Center(
child: Text(
'CLICK ME',
style: TextStyle(
fontWeight: FontWeight.bold, color: Colors.white),
),
),
),
);
}),
),
现在程序运行并在我们点击按钮时显示以下输出