📜  Dart – Builder 类

📅  最后修改于: 2021-09-23 06:43:05             🧑  作者: Mango

每当我们在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),
                ),
              ),
            ),
          );
        }),
      ),

现在程序运行并在我们点击按钮时显示以下输出