当前位置:   article > 正文

Flutter学习笔记---flutter环境搭建以及dart语法的学习_flutter 环境安装

flutter 环境安装

Flutter笔记

Flutter环境搭建

获取 Dart SDK | Dart

dart-pub | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror

Flutter、Dart SDK镜像资源 - 掘金 (juejin.cn)

Index of /flutter/dart-archive/channels/stable/release/3.2.6/sdk/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror


Flutter环境配置(window10环境) - 简书 (jianshu.com)

搞搞flutter,首先是环境配置,此前提是已经安装Android studio和对应的Android SDK。废话不多说,看具体步骤:

一,从如下地址下载对应的flutter SDK,点击如图下载最新版本sdk:

flutterSDK下载地址:https://flutter.dev/docs/get-started/install/windows

在这里插入图片描述

二,将sdk复制到系统盘并解压,位置随意。如下图所示

在这里插入图片描述

三,打开解压的flutter文件夹,找到bin,复制如下图地址

在这里插入图片描述

四,桌面找到 此电脑–>右击选择属性–>高级系统设置–>环境变量–>找到系统变量–>Path–>编辑–>新建–>粘贴第三步复制的地址–>点击确定保存

在这里插入图片描述

五,配置国内镜像。桌面找到 此电脑–>右击选择属性–>高级系统设置–>环境变量–>找到用户变量–>点击新建
FLUTTER_STORAGE_BASE_URL="https://mirrors.tuna.tsinghua.edu.cn/flutter"
PUB_HOSTED_URL="https://mirrors.tuna.tsinghua.edu.cn/dart-pub"
  • 1
  • 2

在这里插入图片描述

六,重启电脑
七,在桌面左下角输入cmd,打开命令提示符。输入 flutter doctor。检查配置项。如下图所示:

在这里插入图片描述

八,发现没有配置Android sdk,补充配置一下,找到用户变量,点击新建,如下图所示。
ANDROID_HOME=D:\AndroidSDK //该sdk地址是你安装Android studio的时候配置的sdk的地址
  • 1

在这里插入图片描述

下图是Android studio中Android SDK的位置:

在这里插入图片描述

九,重新输入cmd,打开命令提示符,输入 flutter doctor,如下图所示:

在这里插入图片描述

十,出现感叹号! Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses按照他说的 输入 flutter doctor --android-licenses,一路y下去即可。如下图所示:

在这里插入图片描述

重新输入 flutter doctor检查一下,如下图所示:表示只有Android studio的两个插件没有安装了。

在这里插入图片描述

十一,打开Android studio,安装dart和flutter两个插件重新运行flutter doctor 如下图:

在这里插入图片描述

都是绿色的小勾勾,表示安装成功。

十一,Android toolchain问题

网上许多教程可能flutter doctor 后直接就是下面的情况:

在这里插入图片描述

此时直接按提示运行flutter doctor --android-licenses 一路按y即可
但现在可没这么简单了,之前也提到过 在安装Android Studio过程中安装的Android sdk时不完整的,所以大多会是

在这里插入图片描述

在这里插入图片描述

根据您的错误提示,您需要进行以下两个步骤来解决Android工具链的问题:

  1. 安装 cmdline-tools 组件
    打开命令行,导航到你的Android SDK的 cmdline-tools 目录。如果尚未下载或安装,可以按照提示在SDK的tools目录下运行以下命令(请将 path/to/sdkmanager 替换为实际的sdkmanager路径):

    path/to/sdkmanager --install "cmdline-tools;latest"
    
    • 1

    这将会安装最新的cmdline-tools组件。

  2. 接受 Android SDK 许可协议
    在命令行中运行以下Flutter命令以接受所有未接受的Android SDK许可:

    flutter doctor --android-licenses
    
    • 1

    然后,当命令行列出所有许可时,按’y’键接受每个许可。

执行完上述步骤后,再次运行 flutter doctor 检查环境是否配置正确。如果一切顺利,关于Android工具链和许可证的状态问题应该会得到解决。

在这里插入图片描述

Android Studio设置国内镜像代理教程(HTTP Proxy)

Android Studio是在谷歌的服务器上,初次安装Android Studio时下载SDK等必定失败,由于国际环境原因,大陆是无法正常访问谷歌的,所以我们在使用Android Studio时需要设置HTTP Proxy 也就是网络代理,下面就来看看操作教程吧。

Android Studio设置HTTP Proxy

1.首次打开会自动弹出HTTP Proxy的设置项,如果没有请进入主界面后点击:File→Settings…→System Settings → HTTP Proxy(或者按快捷键:Ctrl+Alt+S,然后依次找到System Settings → HTTP Proxy)

2.打开后按下图,也就是选中“Auto-detect proxy settings”,勾选下方“Automatic proxy configuration URL”,填入国内的某个镜像站。

3.这里,我选择的是如下镜像站

mirrors.aliyun.com:80
  • 1

4.配置完成后,就可以使用了,其他镜像站请参考下方的“Android SDK在线更新镜像服务器”。

1.阿里云镜像站地址:

mirrors.aliyun.com 端口:80

2.清华大学镜像站地址:

mirrors.tuna.tsinghua.edu.cn 端口:80

3.北京外国语大学镜像站地址:

mirror.bfsu.edu.cn 端口:80

4.中国科学院开源协会镜像站地址:

IPV4/IPV6: mirrors.opencas.cn 端口:80IPV4/IPV6: mirrors.opencas.org 端口:80IPV4/IPV6: mirrors.opencas.ac.cn 端口:80

5.上海GDG镜像服务器地址:

sdk.gdgshanghai.com 端口:8000

6.北京化工大学镜像服务器地址:

IPv4: ubuntu.buct.edu.cn/ 端口:80IPv4: ubuntu.buct.cn/ 端口:80IPv6: ubuntu.buct6.edu.cn/ 端口:80

7.大连东软信息学院镜像服务器地址:

mirrors.neusoft.edu.cn 端口:80

8.腾讯Bugly 镜像:

android-mirror.bugly.qq.com 端口:8080


来源:https://www.jianshu.com/p/fc97fccdf578

Android Studio 国内镜像代理设置(如果设置之后还是远程仓库下载失败,请仔细阅读其内容就可以解决了)-CSDN博客

Android Studio 配置flutter开发环境教程(超详细)_flutter config–android sdk-CSDN博客

使用Android Studio创建项目

  1. 安装flutter插件

    点击pugins直接搜索flutter然后install即可,它会提示此插件依赖dart,直接确定就好
    装好后确定就会回到创建项目页面

在这里插入图片描述

在这里插入图片描述

点击第二项创建flutter project点击next后就是项目配置:

在这里插入图片描述

在这里插入图片描述

dart语言

as关键字

在Dart语言中,as关键字有多种用法:

  1. 类型转换

    • 当你想要将一个对象显式地转换为另一种类型时,可以使用 as 关键字。如果转换是安全的(即目标类型与源类型兼容或者源对象实际上是目标类型的实例),则转换会成功;否则,如果转换失败,则在运行时会抛出 TypeError 异常。

      dynamic value = "Hello";
      String strValue = value as String; // 安全转换,因为value实际是一个String。
      int intValue = value as int; // 不安全转换,如果执行此行代码会抛出TypeError,因为字符串不能直接转换为整数。
      
      • 1
      • 2
      • 3
  2. 库前缀导入

    • 在Dart中,当两个或多个库中有同名的顶级标识符冲突时,可以使用 as 来给导入的库指定别名,以此来避免名称冲突。

      import 'package:lib1/my_library.dart' as lib1;
      import 'package:lib2/my_library.dart' as lib2;
      
      void main() {
        lib1.MyClass classFromLib1 = lib1.MyClass();
        lib2.MyClass classFromLib2 = lib2.MyClass();
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
  3. 异步流(Stream)中的类型过滤

    • 在处理异步数据流时,可以使用 .cast() 方法配合 as 进行类型转换,确保流中的事件符合特定类型。

      Stream<Object> objectStream = ...;
      Stream<String> stringStream = objectStream.cast<String>();
      
      • 1
      • 2
  4. 泛型类和方法中

    • 类型参数上下文中不直接使用 as 关键字,但在类型推断和类型约束中,它可能隐含地用于指示类型转换。

注意:对于异步编程,Dart 使用 asyncawait 关键字而不是 as,这些关键字与异步函数定义以及等待异步操作完成相关联。

dynamic关键字

在Dart语言中,dynamic 是一种类型注解,它表示变量可以持有任何类型的值。当你声明一个变量为 dynamic 类型时,编译器不会对该变量进行类型检查,这给予了你更大的灵活性,但也意味着可能在运行时出现类型错误。

例如,在Dart中:

dynamic value;

value = 42; // 正确,因为整数是合法的Dart对象
value = "Hello"; // 正确,字符串也是合法的Dart对象
value.callSomeMethod(); // 运行时如果value不是一个具有callSomeMethod方法的对象,则会抛出异常

// 在Dartz库的上下文中,
// dynamic 可能用于表示函数式编程中的某种泛型或不特定类型的数据结构,
// 但在Dartz库本身并不直接定义或使用特殊的 dynamic 类型概念。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在与Dartz库相关的函数式编程场景下,虽然Dartz通常鼓励静态类型以确保类型安全,但如果你将Dart的 dynamic 类型用于Dartz库的数据结构如 Maybe<dynamic>Either<dynamic, String> 等,那么这些数据结构将会允许存储任意类型的值,但这会牺牲掉静态类型带来的诸多优势,包括编译时错误检测和IDE智能提示等。

判空运算符—?、??、??=

在Dart语言中,用于空值处理的运算符包括:

  1. 条件成员访问运算符 ?.:

    • 当尝试访问可能为 null 的对象的属性或方法时使用。

      var person = maybeNullPerson; // 可能是 null
      var name = person?.name; // 如果 person 为 null,则 name 也为 null,否则访问 person.name
      
      • 1
      • 2

      这个运算符会安全地返回 null 而不是抛出异常。如果链式调用中的任何一个点为 null,则整个表达式将短路并返回 null

  2. 空合并运算符 ??:

    • 当需要提供一个默认值以防止 null 值时使用。

      String nullableString;
      String nonNullableString = nullableString ?? "default value"; 
      
      • 1
      • 2

      如果 nullableString 为非 null,那么 nonNullableString 将等于 nullableString 的值;如果 nullableStringnull,则 nonNullableString 将被赋予 “default value”。

  3. 空合并赋值运算符 ??=:

    • 只有当变量为 null 时才进行赋值操作。

      String? possiblyNullVar;
      possiblyNullVar ??= "initialized on demand";
      
      • 1
      • 2

      在这个例子中,只有当 possiblyNullVarnull 时,才会执行 possiblyNullVar = "initialized on demand"。如果 possiblyNullVar 已经有一个非 null 的值,此运算符什么都不会做,保持原值不变。

这些运算符都是 Dart 空安全特性的一部分,旨在帮助开发者编写更安全、简洁的代码,避免因意外的 null 引发运行时错误。

switch…case

在Dart语言中,switch...case 语句用于基于表达式的值执行不同的代码块。以下是 switch...case 的基本用法:

// 声明一个变量或表达式
var someValue = ...; // 可以是整数、字符、枚举或其他允许的类型

switch (someValue) {
  case value1:
    // 当 someValue 等于 value1 时执行这里的代码
    statements1;
    break; // 如果需要在执行完statements1后立即跳出switch结构,则使用break

  case value2:
    // 当 someValue 等于 value2 时执行这里的代码
    statements2;
    break;

  // 可以有任意数量的case子句
  ...

  default:
    // 当 someValue 不等于任何一个case标签的值时执行这里的代码
    defaultStatements;
    break; // 在default分支中使用break也是可选的,因为默认情况下会在这里停止执行switch结构
}

// switch 结构结束后的其他代码
...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

注意事项:

  • switch 表达式的结果必须是整数、字符串(从 Dart 2.3 版本开始支持)、或者实现了 == 运算符和 hashCode 方法的对象。
  • 每个 case 子句后面跟着一个要匹配的常量表达式。
  • 执行流程会进入第一个与 switch 表达式结果相等的 case 分支,并执行该分支中的代码。
  • 使用 break 关键字来终止当前 case 分支的执行并跳出整个 switch 结构。如果没有 break,控制流将“贯穿”到下一个 case 子句,直到遇到 break 或到达 switch 结束为止。
  • default 子句是可选的,用于提供一个当所有 case 都不匹配时的默认行为。

Class

您提供的Dart代码片段定义了一个名为 Cat 的类,但是缺少了构造函数来初始化实例的属性。在Dart中,如果你不提供任何构造函数,编译器会自动生成一个无参数的默认构造函数。然而,一旦类中有可nullable的非final字段(如您的 nameage),默认构造函数不会给它们赋予初始值,所以在创建 Cat 实例时这些字段将是未初始化的。

为了让这个类能正确实例化并赋初值,您可以添加一个构造函数:

class Cat {
  String name;
  int age;

  // 添加构造函数以初始化成员变量
  Cat(this.name, this.age);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

现在当你创建 Cat 类的实例时,需要传递 nameage 的初始值:

var myCat = Cat('Mittens', 3); // 创建一个名字为'Mittens'、年龄为3岁的猫实例
  • 1

当然,如果您希望 nameage 在没有传入值时有默认值,可以这样定义构造函数:

class Cat {
  String name;
  int age;

  // 添加构造函数,并设置默认值
  Cat({this.name = '未知', this.age = 0});
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这样即使不传递参数也能创建 Cat 实例,并且其 nameage 将分别默认为 '未知'0

类的构造方法

您提供的代码中包含了两种不同的构造方法(构造函数):

  1. 带有初始化逻辑的构造函数:
Cat(String name, int age) {
  this.name = name; // 使用 'this' 关键字来明确指定当前实例的属性
  this.age = age;
}
  • 1
  • 2
  • 3
  • 4

在这个构造函数中,通过传入的 nameage 参数直接初始化了实例的同名属性。这种方式下,即使成员变量使用了 late 关键字,也会在构造函数执行时立即赋值。

  1. 初始化列表构造函数:
Cat(this.name, this.age);
  • 1

这个构造函数是简化的构造器语法,它使用了初始化列表。当参数名与类中的属性名相同时,可以直接用 this. 的形式来引用它们,并且会自动完成对相应属性的初始化。在这种情况下,由于我们已经提供了初始值,所以对于 late 类型的属性来说也是安全的,它们会在构造过程中被初始化。

结论:这两种构造函数都可以用来正确地初始化带有 late 关键字的 nameage 属性。在实际开发中,如果不需要额外的初始化逻辑,通常更倾向于使用第二种简洁的初始化列表构造函数。

import用法

在Dart中,import 关键字用于导入其他库或源文件中的类、函数或其他定义。以下是 import 的基本用法:

  1. 基本导入

    import 'package:example_package/example_file.dart';
    
    • 1

    这种形式用于导入 pub(Dart的包管理器)依赖或者项目内的库。这里的 'package:example_package/example_file.dart' 表示要导入的文件路径。

  2. 导入并指定别名

    import 'package:example_package/example_file.dart' as myAlias;
    
    • 1

    当需要给导入的库或文件指定一个别名以避免命名冲突时使用此语法。例如,在上面的例子中,你可以通过 myAlias 来引用导入文件中的所有内容。

  3. 仅导入部分内容

    import 'package:example_package/example_file.dart' show MyClass, MyFunction;
    
    • 1

    使用 show 关键字可以指定只导入指定的类或函数等符号。在上述例子中,只会导入 MyClass 类和 MyFunction 函数。
    或者

    import 'package:example_package/example_file.dart' hide MyClass;
    
    • 1

    使用 hide 关键字可以排除指定的类或函数等符号。这意味着除了 MyClass 之外,example_file.dart 中的所有其他内容都会被导入。

  4. deferred import(延迟加载导入):

    import 'package:example_package/example_file.dart' deferred as myDeferredImport;
    
    • 1

    延迟加载导入会在运行时而不是编译时加载库,通常用于大型库以提高应用启动速度。在使用这些库之前,需要通过 .loadLibrary() 方法来加载它们。

  5. 混合使用 show 和 hide

    import 'package:example_package/example_file.dart'
        show MyClass, AnotherClass, hide MyFunction;
    
    • 1
    • 2

    同时使用 showhide 可以更精细地控制导入的内容。

注意:对于 Dart SDK 内置的库,可以直接导入,如:

import 'dart:math'; // 导入Dart内置的数学库
  • 1

枚举类

在Dart语言中,枚举(Enum)是一种特殊的类,用于定义一组命名的、预定义的常量值。枚举可以为这些常量提供有意义的名称,并且每个枚举值都有一个索引和唯一标识。

创建枚举的基本语法如下:

enum Color { 
  red, 
  green, 
  blue 
}
  • 1
  • 2
  • 3
  • 4
  • 5

在这个例子中,Color 是枚举类型的名字,而 redgreenblue 是该枚举类型的三个实例或成员。

每个枚举值都有一个默认索引,从0开始自动递增。例如,red 的索引是 0,green 的索引是 1,blue 的索引是 2。可以通过 .index 属性获取枚举值的索引:

int redIndex = Color.red.index; // redIndex 将会是 0
  • 1

此外,你可以访问枚举的当前值:

Color myColor = Color.green;
print(myColor); // 输出: Color.green
  • 1
  • 2

如果需要自定义枚举值对应的字符串或者其他数据,可以给枚举成员指定一个值:

enum Color {
  red('红色'),
  green('绿色'),
  blue('蓝色');

  final String description;

  Color(this.description);

  String get value => description;
}

void main() {
  print(Color.red.value); // 输出: 红色
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在这个例子中,我们为每个颜色枚举添加了一个描述字段,并提供了获取描述的方法 value

【dart相关问题】

有问题。

/// 可选位置参数---用[]包裹
void insertUser1(int id, String name, [int age]) {
  String intro = "id:$id,name:$name";
  if age:
    intro = intro+"age:$age";
  print(intro);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这段代码中存在几个问题:

  1. 可选位置参数的定义是正确的,但调用时需要在括号内指定或者省略。[int age] 表示 age 是一个可选的位置参数,默认值为 null

  2. 在条件判断中使用了变量 age 而不是 if (age != null)if (age != null && age != '')(如果考虑空字符串的情况)来检查 age 是否有值。

修正后的代码应该是这样:

void insertUser1(int id, String name, [int age]) {
  String intro = "id:$id,name:$name";

  if (age != null) { // 检查 age 是否有非 null 值
    intro += ",age:$age"; // 使用 += 连接字符串而非 +
  }

  print(intro);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

现在,当你调用 insertUser1(1, 'John') 时,不会包含年龄信息;而调用 insertUser1(1, 'John', 30) 时,则会打印出带有年龄信息的结果。

【error】 06-function.dart:30:44: Error: The parameter 'age' can't have a value of 'null' because of its type 'int', but the implicit default value is 'null'. Try adding either an explicit non-'null' default value or the 'required' modifier. void insertUser1(int id, String name, [int age]) { ^^^

我明白了,Dart 2.12 版本引入了空安全特性,并在 Dart 2.13 版本默认开启。这意味着 int 类型的参数不能为 null,但你提供的可选参数 age 没有指定非 null 的默认值。

要解决这个问题,请根据你的需求选择以下任一方式:

  1. 如果 age 参数可以是 null 并且希望保持其为可选参数,则将其类型更改为 int?
void insertUser1(int id, String name, [int? age]) {
  String intro = "id:$id,name:$name";

  if (age != null) {
    intro = "$intro,age:$age";
  }

  print(intro);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  1. 如果 age 参数必须提供一个非 null 值,则移除方括号并添加 required 关键字:
void insertUser1(int id, String name, required int age) {
  String intro = "id:$id,name:$name,age:$age";
  print(intro);
}
  • 1
  • 2
  • 3
  • 4

现在,无论是哪种情况,代码都不会报错,并且符合 Dart 的空安全规范。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/448449
推荐阅读
相关标签
  

闽ICP备14008679号