Flutter Dart构造函数

Iri*_*ngo 11 dart flutter

在flutter Examples页面中,有一个名为"将数据发送到新屏幕"的项目.我有问题在第65行调用构造函数.

将数据发送到新屏幕

  // In the constructor, require a Todo
  DetailScreen({Key key, @required this.todo}) : super(key: key);
Run Code Online (Sandbox Code Playgroud)

什么是超级(键:键)?请问我能解释整行吗?守则在这里......

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

class Todo {
  final String title;
  final String description;

  Todo(this.title, this.description);
}

void main() {
  runApp(MaterialApp(
    title: 'Passing Data',
    home: TodosScreen(
      todos: List.generate(
        20,
            (i) => Todo(
          'Todo $i',
          'A description of what needs to be done for Todo $i',
        ),
      ),
    ),
  ));
}

class TodosScreen extends StatelessWidget {
  final List<Todo> todos;

  TodosScreen({Key key, @required this.todos}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Todos'),
      ),
      body: ListView.builder(
        itemCount: todos.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(todos[index].title),
            // When a user taps on the ListTile, navigate to the DetailScreen.
            // Notice that we're not only creating a DetailScreen, we're
            // also passing the current todo through to it!
            onTap: () {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => DetailScreen(todo: todos[index]),
                ),
              );
            },
          );
        },
      ),
    );
  }
}

class DetailScreen extends StatelessWidget {
  // Declare a field that holds the Todo
  final Todo todo;

  // In the constructor, require a Todo
  DetailScreen({Key key, @required this.todo}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // Use the Todo to create our UI
    return Scaffold(
      appBar: AppBar(
        title: Text("${todo.title}"),
      ),
      body: Padding(
        padding: EdgeInsets.all(16.0),
        child: Text('${todo.description}'),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

Sur*_*gch 14

这是对GünterZöchbauer的解释的补充示例。它是Align小部件的构造函数。

class Align extends SingleChildRenderObjectWidget {

  // constructor
  const Align({
    Key key,                                                   // named parameter
    this.alignment = Alignment.center,                         // named parameter
    this.widthFactor,                                          // named parameter
    this.heightFactor,                                         // named parameter
    Widget child                                               // named parameter
  }) : assert(alignment != null),                              // initializer list
       assert(widthFactor == null || widthFactor >= 0.0),      // initializer list
       assert(heightFactor == null || heightFactor >= 0.0),    // initializer list
       super(key: key, child: child);                          // initializer list

  // class variables
  final AlignmentGeometry alignment;
  final double widthFactor;
  final double heightFactor;
Run Code Online (Sandbox Code Playgroud)

更多说明:

  • 不带this.前缀的参数是超类的变量。
  • 开头的参数是this.当前类中定义的变量。


Gün*_*uer 13

构造函数有两个命名参数.
默认情况下,命名参数是可选的.
@required是Dart分析器识别的注释,如果在构建时调用时未传递,则会产生警告(在运行时无效).

:启动"初始化列表",这是在超类的构造函数之前执行的逗号分层表达式列表,因此也在构造函数体之前执行.
它通常用于使用断言检查参数值并使用计算值初始化最终字段.
一个限制是,表达式无法读取this.(隐式或显式),因为在执行超级构造函数之前未完成对象初始化.

初始化程序中的最后一个元素是对超类的默认构造函数的隐式调用(如果省略),或者调用当前类的特定构造函数或超类(如果给定).

在您的问题的示例中,key传递给构造函数的参数将转发到key超类的未命名构造函数的命名参数.


Roh*_*wal 11

下面是我对Flutter构造函数的详细理解

一个类中只有一个构造函数,但可以有多个工厂方法。

  1. 位置参数

这些是传统参数,按照构造函数中定义的相同顺序传递。

MyWidget(String param1, int param2) {
  debugPrint("Positional Optional $param1, $param2");
}
Run Code Online (Sandbox Code Playgroud)

呼唤

MyWidget('Param 1 Passed',2,)
Run Code Online (Sandbox Code Playgroud)
  1. 命名参数

正如我们引用的那样,flutter 遵循标准实践param_name:value。下面是示例

MyWidget(String param1, {int? param2}) {
  debugPrint("Positional Optional $param1, $param2");
}
Run Code Online (Sandbox Code Playgroud)

呼唤

MyWidget('Param 1 Passed',param2: 2,)
Run Code Online (Sandbox Code Playgroud)
  1. 可选参数

可选参数包含在方括号中[ ]

MyWidget(String param1, [int? param2]) {
  debugPrint("Positional Optional, $param1, $param2");
}
Run Code Online (Sandbox Code Playgroud)

现在,由于参数 2 位于 之间[ ],因此参数 2 成为可选的。所以下面有两种调用方法。

方式一:不传递参数2,如果不传递,构造函数会将其视为null。

MyWidget('Param 1 Passed',)
Run Code Online (Sandbox Code Playgroud)

方式2:传递两个参数

MyWidget('Param 1 Passed',123)
Run Code Online (Sandbox Code Playgroud)
  1. 所需参数

当需要强制传递参数时,我们可以通过使用关键字required{ }.

规则required 不能与可选参数一起使用,即[ ]。显然,如果它是必需参数,则不能将其包装在可选参数中[ ]

MyWidget(String param1, {required int param2}) {
  debugPrint("Positional Optional, $param1, $param2");
}
Run Code Online (Sandbox Code Playgroud)

呼唤

MyWidget('Param 1 Passed', param2: ,123)
Run Code Online (Sandbox Code Playgroud)
  1. 冒号

冒号主要用于构造函数参数初始化。

规则:不能对参数进行初始化,在这种情况下只能对类中声明的变量进行初始化strTxt

String strTxt;

MyWidget(String param1, int param2) : strTxt = "Some Value" {
  debugPrint("Positional Optional, $param1, $param2, $strTxt");
}
Run Code Online (Sandbox Code Playgroud)

呼唤

MyWidget('Param 1 Passed', 123)
Run Code Online (Sandbox Code Playgroud)

debugPrint结果:注意我们设置的日志中的“Some Value”:

位置可选,参数 1 已通过,123,某些值

  1. Body 它只是大括号内的内容。

在此输入图像描述

  1. 通过参数直接赋值

您可能还记得,在 Android 和其他一些语言中,我们在参数中传递值,然后将其与类级别变量等同。在 Flutter 中,只需使用 即可完全缩短此时间this.class_level_var_name。它只是将传递的值分配给该类级别变量。

MyWidget(this.strTxt, int param2) {
  debugPrint("Positional Optional, $strTxt, $param2");
}
Run Code Online (Sandbox Code Playgroud)

呼唤

MyWidget('Param 1 Passed', 123)
Run Code Online (Sandbox Code Playgroud)

结果

Positional Optional, Param 1 Passed, 123
Run Code Online (Sandbox Code Playgroud)
  1. 可空?ORrequired声明

仅当我们将参数设为可选[ ]或 Named时才需要声明可为 null { },对于定义为正常的参数,不需要required或可为 null?

通知?param2

MyWidget(this.strTxt, {int? param2}) {
  debugPrint("Positional Optional, $strTxt, $param2, $strTxt");
}
Run Code Online (Sandbox Code Playgroud)

注意required

MyWidget(this.strTxt, {required int param2}) {
  debugPrint("Positional Optional, $strTxt, $param2, $strTxt");
}
Run Code Online (Sandbox Code Playgroud)