flutter笔记-hello dart

发布于:2024-04-26 ⋅ 阅读:(21) ⋅ 点赞:(0)

1. 搭建环境

环境的搭建在window和mac都差不多,都是从官网下载对应操作系统对应版本的SDK;
然后就是配置flutter下的bin到对应系统的环境变量,我这里是mac使用的zsh,配置.zshrc 或者.zsh_profile等文件我的配置如下:

 flutter 配置
export PUB_HOSTED_URL="https://pub.flutter-io.cn"
export FLUTTER_STORAGE_BASE_URL="https://storage.flutter-io.cn"
export FLUTTER_HOME=$HOME/dev/flutter
export PATH="$PATH:$FLUTTER_HOME/bin"
export PATH="$PATH:$FLUTTER_HOME/bin/cache/dart-sdk/bin"

2. 运行官方首个程序

flutter安装完毕后,创建一个工作目录,用来存放flutter项目;然后再当前目录执行 :

 flutter create hello_flutter 

关于包名,要求如下:

  • 包名应该全部小写just_like_this
  • 用下划线分隔单词
  • 仅使用基本拉丁字母和阿拉伯数字:[a-z0-9_]
  • 确保该名称是有效的 Dart 标识符——它不以数字开头,也不是保留字。
    如果出现大写就会出现下列错误:
"Hello_word" is not a valid Dart package name.

The name should be all lowercase, with underscores to separate words,
"just_like_this".Use only basic Latin letters and Arabic digits: [a-z0-9_].Also,
make sure the name is a valid Dart identifier—that it doesn't start with digits
and isn't a reserved word.
See https://dart.dev/tools/pub/pubspec#name for more information.
Try "hello_word" instead.

其他注意事项见:https://dart.dev/tools/pub/pubspec#name

3. AS中运行

打开AS 选择打开已经存在的项目,选择文件,然后就可以在AS种编译了;

iOS

在AS中启动iOS模拟器要是启动设备,检查下默认xcode,因为我有多个xocde默认没有选择不是系统的所以云信iOS模拟器失败;AS中默认启动的是application下的xcode模拟器;可以使用命令:

 xcode-select -p
 sudo xcode-select --s /Applications/Xcode.app/Contents/Developer

Android

Android studio运行官方demo出现以下错误:

Exception in thread “main” java.util.zip.ZipException: zip END header not found
...

通过在其官方的issue中找到错误原因:这个错误与 Gradle 有关,这个错误通常是由于 Gradle 设置损坏或不完整所导致的,解决步骤如下:

  • 转到用户根目录并找到隐藏.gradle文件夹并将其删除。
    如果您使用的是 Mac,请打开终端并执行
cd ~
rm -rf .gradle
  • 然后运行你的应用程序到 Android 模拟器或设备(Physical device),不要取消,并确保有稳定的互联网连接(国内可能需要…),在这时候AS将自动下载新的 Gradle;
  • 下载完成后,项目运行成功;如图:
    在这里插入图片描述

语法简述

1. 变量常量

在Dart中支持显示声明和类型推导,如下:

 // 显示声明
  String name = "Aman";
  // 类型推导
  var age = 20;
  // 可修改
  name = "Aman1";
  age = 21;
  print("name is ${name},age is ${age}");
  1. 常量
    有两种声明方式 final 和 const
/  final
  final String add = "test";
  // add = "test1"; //不可修改
  // const
  const String add1 = "test2";
  // add1 = "test3"; // 不可修改

这两个的区别是,const 必须赋值常量值,是要在编译期间确定的值;final可以是运行期间确定的值;如下:

 // final var timer = DateTime.now().millisecondsSinceEpoch;//推导类型不能用于 const和 final
  final int timer = DateTime.now().millisecondsSinceEpoch;

  // const int timer1 = DateTime.now().millisecondsSinceEpoch;//const 必须是常量值
  const int timer2 = 3333;

在日常开发中常用final;例如:

class Person {
  String name;
  int age;
  Person(this.name, this.age);
}
final p = Person("Aman", 20);
final p1 = Person("Andy", 38);//这里2.0之前需要使用 const Person("Andy", 38)
print(identical(p, p1));
// false

其中identical使用与判断两个对象是否相等;
上面的实例也介绍其中的dart的类定义;
const示例:

const p_c = Person("LiSi",
      50); //这样报错:The constructor being called isn't a const constructor.
  const p_c1 = Person("VeLi", 58);
  print("const 比较:${identical(p_c, p_c1)}");
  // false

类需要修改:

class Person {
  final name;
  final age;
  const Person(this.name, this.age);
}

也就是要把构造器改成const的;通过上面的输出也能知道这样 写并不是单例;

需要注意的是dart中没有非空即真,也就是判断一个对象是否存在,需要明确的bool类型;例如:

  String name = "Aman";
 if (name) {
    
  }

会报错:Conditions must have a static type of 'bool'.

字符串补充

dart支持类似Python的多行字符串定义:

var str = """
  这里都是字符串
  """;
  print(str);

2. 集合

和大多数语言类似。这里直接看示例:

void main(List<String> args) {
  // 集合 list [] 字面量创建
  var name = ['a', 'b', 'c'];
  for (var item in name) {
    print(item);
  }

  // set {}字面量创建
  var set = {1, 2, 3, 4, 5};
  for (var element in set) {
    print(element);
  }
  // map
  var map = {
    'name': 'zhangsan',
    'age': 18,
    'sex': '男',
  };
  for (var key in map.keys) {
    print(key);
  }
}

3. 函数

dart中不支持函数重载,参数有可选参数(位置可选参数和命名可选参数)和必传参数:
// 必传参数

testString(String name) {
  print(name);
}

// 位置可选参数
testopt(String name, [int age = 0, double weight = 0.0]) {
  print(name);
}

// 命名可选参数
TestsOpt1(String name, {int age = 0, double weight = 0.0}) {
  print(name);
}

调用:

testString("dddd");
  testopt("ddd", 4, 6.0);
  TestsOpt1("444", age: 1, weight: 9);

关于可选报错:

The parameter 'num' 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. 

在这里插入图片描述

修改成这样:

int add(int a, int b, {String name = "", int num = 0}) {
  return a + b;
}

匿名函数

function是dart保留词,其使用如下:

testFun(Function f) {
  f("5454");
}
调用:
testFun((test) {
    print(test);
  });

注意Function是无参数的,在实例中是可以使用传参的所以一般使用如下:

typedef TestFunP = void Function(String name);
testFun1(TestFunP f) {
  f("5454");
}

4. 特殊运算符

dart中大部分的运算符和其他语言类似;

  • ??=使用如下:
   // 赋值运算符 当原来的变量不是空的时候才会赋值
  var name = "10";
  name ??= "123";
  print(name);
  • 级联运算符 …
   class Person {
  var name;
  var age;
  Person(this.name, this.age);
  run() {
    print("run:${this.name} ${this.age}");
  }

  eat() {
    print("eat:${this.name} ${this.age}");
  }
}

var per = Person("ddd", 1)
    ..name
    ..run()
    ..eat();

相当于类中函数的链式调用;

5. 类

语法和c++类似,有默认构造函数,如果有自定义构造函数那么就会覆盖默认构造函数;自定义构造函数与其他语言不同的是。类似上面实例的调用:

Person(this.name, this.age);

这种事dart的一种语法糖;

  • 由于Dart不支持函数重载;类似不同参数的构造实现可以使用**命名构造函数**;
   // 命名构造函数
  Person.withNameAgeWeight(this.name, this.age, this.weight);
  Person.fromMap(Map<String, dynamic> map) {
    this.name = map["name"];
    this.age = map["age"];
    this.weight = map["weight"];
  }
  • 类的初始化列表
  Person(this.name, {int age = 10}) : this.age = age ?? 10;

dart 包

上面使用的方法都是在dart/core中所以不用导入可以使用,其他库比如math库的导入方法如下:

import 'dart:math' show max, sqrt;//show 只引入库里面的某个方法, hide 不导入某个方法导入其他方法

一般情况下.dart就是一个包或者叫库;

第三方库的使用是通过yaml文件实现;
也就是新建pubspec.yaml中引入,具体格式见官方;
常用格式如下:

environment:
  sdk: ">=2.12.0 <3.0.0"
  flutter: ">=1.17.0"

name: flutter_app
description: A new Flutter project.
dependencies:
  flutter:
    sdk: flutter
  http: ^1.2.1
  • 然后到yaml所在的目录执行 dart pub get 就会下载所有的这个库的依赖和这个库如图:
    *在这里插入图片描述

  • dart pub get这个命令执行完毕后会根据pubspec.yaml中配置的内容下载对应的包,并放置在系统缓存中(包括其依赖的所有包);

在Mac或者Linux系统中,这个缓存目录的地址是:~/.pub-cache,在windows中这个目录地址是:%LOCALAPPDATA%\Pub\Cache;也可以通过设置PUB_CACHE更改缓存地址;

  • 当下载完依赖包之后,dart会在 .dart_tool/目录中创建一个 package_config.json文件,用来表示当前项目和系统缓存包的映射关系。
    注意在3.0以后的版本使用dart需要如下导入库:
import 'package:http/http.dart' as http;

然后就可以按照官方的实例运行:

import 'dart:convert' as convert;
import 'package:http/http.dart' as http;

void main(List<String> args) async {
  // This example uses the Google Books API to search for books about http.
  // https://developers.google.com/books/docs/overview
  var url =
      Uri.https('developers.google.com', '/books/v1/volumes', {'q': '{http}'});

  // Await the http get response, then decode the json-formatted response.
  var response = await http.get(url);
  if (response.statusCode == 200) {
    var jsonResponse =
        convert.jsonDecode(response.body) as Map<String, dynamic>;
    var itemCount = jsonResponse['totalItems'];
    print('Number of books about http: $itemCount.');
  } else {
    print('Request failed with status: ${response.statusCode}.');
  }
}