在 Flutter 保持所有常数的最佳实践是什么?

在 Flutter 创建一个常量类来保存所有应用程序常量以便于参考的最佳编程实践是什么?

我知道 Dart 中有一个 const关键字用于创建常量字段,但是可以将 staticconst一起使用吗,或者它会在运行时创建内存问题。

class Constants {
static const String SUCCESS_MESSAGE = "You will be contacted by us very soon.";
}

这个问题不仅基于获得适当的结构,还基于知道如何在创建常量时节省资源和防止内存泄漏。

87741 次浏览

这完全取决于你。
使用静态没有缺点。
实际上,类中的字段需要 const

剪辑

现在,标志 --dart-define已经添加到 Flutter 的不同命令行中,以下答案不再适用。

相反,只需在任何需要的地方声明常量,并可能引用其他答案。


虽然 static const没有任何技术问题,但是在架构上您可能希望采用不同的方法。

Flutter 趋向于 没有具有任何全局/静态变量,并且使用 Heritage itedWidget。

这意味着你可以写:

class MyConstants extends InheritedWidget {
static MyConstants of(BuildContext context) => context. dependOnInheritedWidgetOfExactType<MyConstants>();


const MyConstants({Widget child, Key key}): super(key: key, child: child);


final String successMessage = 'Some message';


@override
bool updateShouldNotify(MyConstants oldWidget) => false;
}

然后插入到你的应用程序的根目录:

void main() {
runApp(
MyConstants(
child: MyApp(),
),
);
}

用作:

@override
Widget build(BuilContext context) {
return Text(MyConstants.of(context).successMessage);
}

这比 static const的代码多一点,但有很多优点:

  • 可以用热装填
  • 易于测试和模拟
  • 可以用比常量更动态的东西替换,而无需重写整个应用程序。

但与此同时:

  1. 不会消耗更多的内存(继承的小部件通常只创建一次)
  2. 是性能的(获取一个 Heritage itedWidget 是 O (1))

我的首选解决方案是使我自己的达特库。

创建一个名为 constants.dart的 Dart 文件,并添加以下代码:

const String SUCCESS_MESSAGE=" You will be contacted by us very soon.";

编辑: 99% 的情况下,您不需要在文件的顶部显式命名您的 dart 库,并且您可能不应该(参考文献)使用像 library library_name;这样的语句。
即使你省略了这一行,你的文件仍然是库! 它只是被隐式命名。

然后将以下导入语句添加到任何需要访问常量的 Dart 文件的顶部:

import 'constants.dart' as Constants;

注意,如果 constants.dart位于不同的目录中,那么您需要在 import 语句中指定到 constants.dart的路径。

编辑: 在指定库前缀时使用 lowercase_with_underscores

在这个例子中:

enter image description here

你可以使用一个相对路径:

import '../assets/constants.dart' as constants;

或者 lib 目录中的绝对路径:

import 'package:<your_app_name>/assets/constants.dart' as constants;

现在,您可以使用以下语法轻松地访问常量:

String a = Constants.SUCCESS_MESSAGE;

对于所有常量,只需在 lib 文件夹或 lib/util 文件夹下创建 Constants.dart 文件,然后保持所有常量变量如下:

 const SUCCESS_MESSAGE=" You will be contacted by us very soon.";


// Api related
const apiBaseURL = "https://baseurl.com";
    

const userLoginApi = "login";
const userSignupApi = "signup";
    

// Shared Preference keys
const kDeviceName = "device_name";
const kDeviceUDID = "device_id";


// Asset Constants
const navBarLogoImage = "assets/images/home_images/sample.png
   

然后在必需类中导入 Constants.dart 文件并直接使用它。

Dart 文档明确表示“避免定义只包含静态成员的类”

我使用的方法是创建一个或多个文件来存储这些常量。有时,当您的项目太大时,可能会有很多这样的文件,为了加载更少的数据,我更喜欢根据不同的上下文将它们分开,我会使用它们创建单独的文件。 所以我只导入我会用到的那些。

我喜欢这样组织我的“常数”。对我来说,保持组织性和跟踪已经存在的东西更容易。 我可以做这样的东西: Tables.questions.idTables.anwerOptions.orderIndex

class Tables {
static QuestionsTable get questions => QuestionsTable();
static AnswerOptionsTable get answerOptions => AnswerOptionsTable();
}


class QuestionsTable {
String get id => "id";
String get title => "question";
String get subtitle => "description";
String get inputFieldType => "answer_input_type";
String get answer => "answer";
}


class AnswerOptionsTable {
String get id => "id";
String get questionId => "question_id";
String get answerOption => "answer_option";
String get orderIndex => "order_index";
}

指的是 https://dart.dev/guides/language/effective-dart/design

在类中对常量和类枚举类型进行分组是一个很好的实践,如下所示:

enter image description here

在 Android Studio 中,自动导入非常简单,您可以输入类名 颜色,Android Studio 将能够建议自动导入 颜色类。

我注意到这里的答案有点混乱,所以我想我应该试着澄清一些事情。

Dart/Flutter 指导方针建议不要创建只包含静态成员的类,即因为它不是必需的。有些语言,比如 Java 或 C # 不允许在类之外定义函数、变量或常量,但是 Dart 允许。因此,您可以简单地创建一个包含要定义的常量的文件,比如 常数,飞镖

正如@Abhishek Jain 所指出的,这个方法不需要 library关键字。library关键字用于将在其他项目中发布使用的库,尽管它可以与 partpart of一起使用,以便在多个文件之间分解单个库。然而,如果您需要它,那么您的需求可能超出了 OP 的问题范围。

正如@ChinLoong 所指出的,创建一个对相关常量和类枚举类型进行分组的类在技术上是可以接受的。然而,应当指出,这表明该准则有例外,因为它不是一条硬性规则。虽然这是可能的,但是在 Dart 中,定义一个从未实例化的类是不可取的。您会注意到,定义 Color 常量的 Dart Color 类有一个构造函数,它除了一个整数值之外,还允许对未由常量定义的颜色进行实例化。

总之,最好遵循 Dart 指导方针的方法是创建一个 常数,飞镖文件或包含不同常量(绳子,飞镖时尚,飞镖等)的多个文件的常量文件夹。在 常数,飞镖文件中,在顶层定义常量。

// constants.dart
 

const String SUCCESS_MESSAGE=" You will be contacted by us very soon.";


...

然后,将需要使用常量的地方的文件 import化,并通过常量的名称直接访问该文件。

最好的解决方案 是创建一个外部文件,在其中创建一个类,然后在其中添加所有常量。

举个例子:

constant.dart中,您将创建常量类

 import 'package:flutter/material.dart';
class Constant {
static Color myColor = Colors.blue;
static Icon myIcon = Icon(Icons.search , color: Colors.red,);
static TextStyle myStyle = TextStyle(
fontSize: 17,
fontWeight: FontWeight.bold ,
color: Colors.green);
}

我必须将 material.dart导入到 constant.dart文件中,因为我创建了 Widget 类型常量。这些小部件包含在 Materials. dart 中。如果它只是关于省道对象,如 int,String 等。我不需要。

enter image description here

用法:

Column(
children: [
Text('Hello World' ,style: Constant.myStyle,),
IconButton(icon: Constant.myIcon, onPressed: (){} ),
Divider(color: Constant.myColor,)
],
),

产出:

enter image description here

不要忘记导入文件的库,其中包含 常量,在我的例子中,它是 constant.dart

创建一个名为 constants.dart的 Dart 文件,并添加以下代码:

这种方法为您提供带 (context)或不带 (context)的常量值:

= > 结合上下文:

import 'package:flutter/material.dart';


Color backgroundColor(context) {
return Theme.of(context).backgroundColor;
}

或者

= > 没有上下文:

static Color colorB = Colors.blue;

enter image description here

= > 用法:

  Container(
color: backgroundColor(context),
child: Text('With context'),
),




//or




Container(
color: colorB,
child: Text('With context'),
),

enter image description here

我个人喜欢这个包 Flutter _ gen 4.1.5添加常量不仅限于字符串,这个包还帮助你的颜色,资产,字体等(总之,你可以处理所有常量)

用于资产、字体、颜色的 Flutter 代码生成器ーー删除所有基于 String 的 API。

下面是示例 Flutter _ gen/example

注意,dart 语言支持在类之外定义常量,因此许多人建议为常量创建一个单独的文件并导入它,这对于在项目中工作的单个编码器来说效果很好。

考虑到在同一个项目中工作的多个编码器,在类中隔离常量声明是一个很好的实践,对于支持面向对象编程的语言来说是一个很好的实践