Flutter-Dart入门,常用细节

背景

Dart 诞生于 2011 年,但是在 2017 之前并不是很受欢迎。 在 2017 年 Google 宣布了跨平台移动应用开发的 Flutter beta 版之后,Dart 的受欢迎程度一直在上升。
它被用于web、服务器、移动应用和物联网等领域的开发。

入门

变量

var

Dart 本身是一个强类型语言,任何变量都是有确定类型的,在 Dart 中,当用var声明一个变量后,Dart 在编译时会根据第一次赋值数据的类型来推断其类型,编译结束后其类型就已经被确定。

var t = "flutter";
t=10;/// 报错

dynamic 和 Object

Object 是 Dart 所有对象的根基类,dynamic与Object声明的变量都可以赋值任意对象,且后期可以改变赋值的类型,这和 var 是不同的。
具体不同,后面会介绍。

dynamic a = "123";
Object b = "123";

数据类型

dart2.12加入空安全。
在dart中的一切皆是对象,包括数字、布尔值、函数等,它们和Java一样都继承于Object,所以它们的默认值也就是null(dart2.12之前默认值是null,2.12之后必须赋初值)。在dart主要有: 布尔类型bool、数字类型num(数字类型又分为int,double,并且两者父类都是num)、字符串类型String、集合类型(List, Set, Map)。

结构:【类型】【变量名】= 【赋值】

/// 变量-数据类型
void variable() {
  var t = "hi world";
  bool isBool = false;
  String name = "flutter";
  int age = 1;
  double height = -12.1;

  /// 扩展,直接使用数学函数
  // print("height ${height.abs()}");

  //打印类型
  print(t.runtimeType);
  print(isBool.runtimeType);
  print(name.runtimeType);
  print(age.runtimeType);
  print(height.runtimeType);
}

运行结果:

String
bool
String
int
double

细节一:num类型的变量,自带了数学函数Math功能,不像其他语言

double height = -12.1;
print("height ${height.abs()}");
/// 输出12.1

集合

new 关键词是可选的,创建对象,不需要显示声明关键字new。

/// 集合操作
void collection() {
  List<String> colorList = ['red', 'yellow', 'blue', 'green'];
  /// 语法提示,不需要使用new关键字
  // List<String> colorList2 = new List.empty();

  /// forEach箭头函数遍历
  colorList.forEach((String color) => print(color));

  /// map函数的使用
  print(colorList.map((color) => '1+$color').join(","));

  /// 直接使用{}形式初始化
  Set<String> colorSet = {'red', 'yellow', 'blue', 'green'};
  /// for-in遍历
  for (var color in colorSet) {
    print(color);
  }

  /// map初始化
  Map<String, int> colorMap = {'white': 0xffffffff, 'black': 0xff000000};
  print(colorMap.containsKey('green')); //false
  print(colorMap.containsValue(0xff000000)); //true

}

空安全null safety

从dart 2.12开始,支持空安全。就是在类型后面加个?

  1. 确保正确性
  2. 在编译时就能确定数据类型,避免为null的情况
/// 空安全
void nullSafety(){
  /// 默认是null
  String? nullStr;
  int? nullInt;
  bool? nullBool;
  Map<String, int>? nullMap;

  print("init nullStr = $nullStr");

  /// 报错,Error: Non-nullable variable 'str' must be assigned before it can be used.
  String str;
  // str = "init";
  print("is $str");

}

如果使用String str 申明变量,但又不初始化,在使用的时候就会报错误。

late延时/惰性初始化

正式使用它之前必须得保证初始化过了,否则会报错

  1. 可能不需要该变量,并且初始化它的成本很高。
  2. 这个变量可能从网络获取。
void main() {
  var awesome = Awesome();
  print('awesome: ${awesome.isAwesome}');

  lateVoid();
}

/// 可以先不初始化
late String description;
void lateVoid() {
  description = 'Flutter!';
  print(description);
}

类型推导var、dynamic、object

前面介绍了dart中常用的变量,还可以使用var、dynamic、object用于定义变量,通过这种方式定义变量不需要指定变量类型。

在这里插入图片描述
补充:从图上可以知道object是类型的基类。

使用var、dynamic、object,可以不用指明变量类型。他们区别是什么:
var,编译时会检测类型,如果类型推断出是string类型,再赋值int,会报错。
dynamic,类型是可变的,先复制string再复制int是可以的,编译时不会揣测数据类型,但是运行时会推断。
Object,类型是可变的,先复制string再复制int是可以的,编译时会检测类型。

void varAndDynamic(){

  /// var定义的类型是不可变的,类型推断出是string类型,再赋值int,会报错
  //var
  var str = "flutter";
  print(str.runtimeType); //String
  print(str); //hello world
  // str = 1;

  //dynamic
  /// 编译时不会揣测数据类型,但是运行时会推断
  dynamic mic = "flutter";//编译时不会揣测数据类型,但是运行时会推断
  print(mic.runtimeType);//String
  print(mic);//hello world
  /// 但是这样的坏处就是会让dart的语法检查失效,所以有可能会造成混乱而不报错,所以不要直接使用dynamic
  mic.foo();
  /// 通过它定义的变量会关闭类型检查,这段代码静态类型检查不会报错,但是运行时会crash,因为mic并没有foo()方法,
  /// 所以建议大家在编程时不要直接使用dynamic
  mic=1;
  print(mic.runtimeType);//int 说明类型是可变的
  print(mic);//1

  //Object
  Object object = "flutter";
  print(object.runtimeType);//String
  print(object);//hello world
  object=1;
  print(object.runtimeType);//int 说明类型是可变的
  print(object);//1
  //object.foo();静态类型检查会运行报错会报错
  object.foo();

}

Final 和 Const关键词

如果你不想更改一个变量,可以使用关键字 final 或者 const 修饰变量。一个 final 变量只可以被赋值一次;一个 const 变量是一个编译时常量(const 变量同时也是 final 的)。

final:其值在初始化后不可改变;
const:只能被设一次值,在声明处赋值,且值必须为编译时常量;用于修饰常量。

/// final和const
void finalAndConst(){

  /// 可以用做静态常量
  const int age = 20;

  /// final不能改变
  final String name = 'Flutter';
  /// 以下不能改变
  // name = "zzb";
  print("name $name");

  final int count = 2 * 2;

  /// final只用来修饰变量,但无法限制变量的实例内部发生改变
  final baz = [1];
  // baz=[1,2,3,4]; //出错 此调用修改了变量的实例 即:[1] 和[1,2,3,4]是不同的对象
  baz[0] = 2; //正常执行,只修改了变量引用对象的成员变量的值
  print(baz);


  /// 对比不同点,打印时间
  final String finalTimeStamp = DateTime.now().toString();
  const String constTimeStamp = DateTime.now().toString();//出错,编译时就要确认内容
  
  print("finalTimeStamp $finalTimeStamp");
}

Assert(断言)

在dart中如果条件表达式结果不满足条件(表达式为false),则可以使用 assert 语句中断代码的执行。特别是在Flutter源码中随处可见都是assert断言的使用。注意: 断言只在检查模式(debug调试)下运行有效,如果在生产模式运行,则断言不会执行。

assert(text != null);//text为null,就会中断后续代码执行
assert(urlString.startsWith('https'));
补充

官方不推荐使用forEach方法进行,建议使用for…in替换。

void collection() {
  List<String> colorList = ['red', 'yellow', 'blue', 'green'];

  /// forEach箭头函数遍历
  colorList.forEach((String color) => print(color));
 }

lint语法检测:给出的提示
foreach与fon-in方法pk forEach方法在回调方法出现的弊端。

函数

Dart是一种真正的面向对象的语言,所以即使是函数也是对象,并且有一个类型Function。

函数声明

返回类型,函数名,入参

bool isNull(int? num) {
  return num == null;
}

如果函数体内只包含一个表达式,你可以使用简写语法:

bool isNull2 (int? num) => num == null;

Dart函数声明如果没有显式声明返回值类型时会默认当做dynamic处理,注意,函数返回值没有类型推断,不建议使用

isNull3(int? num) {
  return num == null;
}

参数

有两种形式的参数:必要参数 和 可选参数。必要参数定义在参数列表前面,可选参数则定义在必要参数后面。可选参数可以是 命名的位置的

/// 必选参数
void upload(String filePath, String fileName, int? fileSize) {
}

/// 命名位置参数
void upload2(String filePath, String fileName, {int? fileSize}) {
}

/// 可选位置参数
void upload3(String filePath, String fileName, [int? fileSize]) {
}

/// 测试以上方法
/// 测试以上方法
void testParam(){
  /// 必选参数
  upload("/user", "name", 0);
  /// 命名位置参数,两种用法
  upload2("/user", "name");
  upload2("/user", "name", fileSize: 10);

  /// 可选位置参数
  upload3("/user", "name");
  upload3("/user", "name", 10);
  

}

可选命名参数在Flutter中使用非常多。注意,不能同时使用可选的位置参数和可选的命名参数。
命名位置参数,最大的好处是能知道,传递参数的含义,再配上关键词required,required表示这个参数是必须的。

/// required使用
void upload4({required String filePath, required String fileName, int? fileSize}) {
}
/// required使用
  upload4(filePath: "/user", fileName: "name");
  upload4(filePath: "/user", fileName: "name", fileSize: 10);

对象的 成员 由函数和数据(即 方法 和 实例变量)组成。

默认构造函数

如果你没有声明构造函数,那么 Dart 会自动生成一个无参数的构造函数并且该构造函数会调用其父类的无参数构造方法。

/// 默认构造函数
class Point{
  int x = 0;
  int y = 0;
}
Point point = Point();

有参构造函数和命名式构造函数

需要注意的是:使用了有参构造函数和命名式构造函数,那默认的构造函数就无效了。无法直接使用
Point point = Point();

构造函数:声明一个与类名一样的函数即可声明一个构造函数。
命名式构造函数:可以为一个类声明多个命名式构造函数来表达更明确的意图:

class Point {
  int x = 0;
  int y = 0;
  int? z = 0;

  /// constructor,构造函数,有参数构造函数
  Point(int x, int y) {
    this.x = x;
    this.y = y;
  }

  /// 简化,构造函数
  // Point(this.x, this.y);

  /// 命名式构造函数,明确知道意图
  Point.origin() {
    x = 5;
    y = 5;
  }

  /// 常用命名式构造函数,把json的数据转成对象
  Point.fromJson(Map<String, dynamic> json) {
    x = json['x'];
    y = json['y'];
  }

  void printPoint() {
    print("x = $x y = $y");
  }

  /// 距离
  int distanceTo() {
    return 0;
  }
}

/// 测试构造函数
void testPoint() {
  /// 无法直接使用
  // Point point = Point();

  /// 构造函数
  Point point = Point(2, 2);
  point.printPoint();

  /// 命名式构造函数
  Point point2 = Point.origin();
  point2.printPoint();

  /// 命名式构造函数
  Point point3 = Point.fromJson({'x': 1, 'y': 2});
  point3.printPoint();

  /// 可以为空的对象,调用方法前可以使用运算符?. 来判断是否有该方法
  /// 可以避免因为左边表达式为 null 而导致的问题
  Point? point4;
  point4?.printPoint();
}

私有属性、私有方法

  1. Dart和其他面向对象语言不一样,Data中没有 public private protected这些访问修饰符合,但是我们可以使用_把一个属性或者方法定义成私有。

  2. 私有方法必须要抽离在单独文件中,否则不生效。

class PrivateClass{
  /// 私有变量
  int _i = 1;
  int j = 2;

  PrivateClass();

  void printContent() {
    print("打印变量_i = $_i j = $j");
  }

  /// 私有方法,
  void _printContent2(){
    print("打印变量_i = $_i j = $j");
  }
}

PrivateClass privateClass = PrivateClass();
  privateClass.printContent();

  /// 修改公共属性
  privateClass.j = 3;
  privateClass.printContent();

  /// 无法修改私有属性,报错The setter '_i' isn't defined for the type 'PrivateClass'.
  privateClass._i = 3;

  /// 无法使用私有方法,The method '_printContent2' isn't defined for the type 'PrivateClass'.
  privateClass._printContent2();

继承

如果父类没有匿名无参数构造函数,那么子类必须调用父类的其中一个构造函数。
1.子类使用extends关键词来继承父类

2.子类会继承父类里面可见的属性和方法,但是不会继承构造函数

3.子类能复写父类的方法 getter和setter

class Person {
  String? firstName;

  Person.fromJson(Map data) {
    print('in Person');
  }

  void eat() {
    print("eat");
  }

  void play(){
    print("play");
  }
}

class Teacher extends Person {
  Teacher.fromJson(Map data) : super.fromJson(data) {
    print('in Teacher');
  }

  /// 重写类成员
  @override
  void eat() {
    /// 调用父类方法
    super.play();
    print("eat fish");
  }
}

/// 测试继承
void testExtends() {
  Teacher teacher = Teacher.fromJson({});
  teacher.eat();
}

输出

in Person
in Teacher
play
eat fish

Mixin

Dart 是不支持多继承的,Mixin 是一种在多重继承中复用某个类中代码的方法模式,“组合”类可以访问mixin类的方法、变量而不必成为其子类。使用 with 关键字来使用 Mixin 模式。

定义一个 Person 类,实现吃饭、说话、走路和写代码功能,同时定义一个 Dog 类,实现吃饭、和走路功能:

/// 定义一个 Person 类,实现吃饭、说话、走路和写代码功能,同时定义一个 Dog 类,实现吃饭、和走路功
class Person {
  say() {
    print('say');
  }
}

mixin Eat {
  eat() {
    print('eat');
  }
}

mixin Walk {
  walk() {
    print('walk');
  }
}

mixin Code {
  code() {
    print('code');
  }
}

class Dog with Eat, Walk{}
class Man extends Person with Eat, Walk, Code{}

/// 测试mixin
void testMixin(){
  Man man = Man();
  man.say();//say
  man.code(); //code
  man.eat();//eat

  Dog dog = Dog();
  dog.eat(); //eat
}

打印结果

say
code
eat
eat

mixins是普通的类,我们可以从中扩展方法(或变量)而不扩展类。
Dart之Mixin详解,Flutter中大量使用了这种方式。

异步支持

Dart类库有非常多的返回Future或者Stream对象的函数。 这些函数被称为异步函数:它们只会在设置好一些耗时操作之后返回,比如像 IO操作。而不是等到这个操作完成。

async和await关键词支持了异步编程,允许您写出和同步代码很像的异步代码。

Future

Future与JavaScript中的Promise非常相似,表示一个异步操作的最终完成(或失败)及其结果值的表示。Future 的所有API的返回值仍然是一个Future对象,所以可以很方便的进行链式调用。

/// 测试future
void testFuture() {
  print("start future");
  Future.delayed(Duration(seconds: 2), () {
    throw ArgumentError("Error");
    // return "hi world!";
  }).then((data) {
    print(data);
  }).catchError((e){
    //执行失败会走到这里
    print("失败了 $e");
  });
  print("end future");
}

执行结果:

start future
end future
失败了 Invalid argument(s): Error

就可以说明Future是一个异步操作。

Future 的常用函数

  1. Future.then()
    任务执行完成会进入这里,能够获得返回的执行结果。
  2. Future.catchError()
    有任务执行失败,可以在这里捕获异常。
  3. Future.whenComplete()
    当任务停止时,不断成功或失败,最后会执行这里。
  4. Future.wait()
    可以等待多个异步任务执行完成后,再调用 then()。
    只有有一个执行失败,就会进入 catchError()。
  5. Future.delayed()
    延迟执行一个延时任务。
  6. Future.sync()
    同步执行
  7. Future.microtask()
    创建一个在微任务队列里运行的Future

Future.wait

比如我们有一个界面,需要先分别从两个网络接口获取数据,获取成功后,我们需要将两个接口数据进行特定的处理后再显示到UI界面上。它接受一个Future数组参数,只有数组中所有Future都执行成功后,才会触发then的成功回调,只要有一个Future执行失败,就会触发错误回调。

void testFutureWait(){

  Future<String> demo1() {
    return Future.value("1");
  }
  Future<String> demo2(){
    return Future.value("2");
  }
  Future<dynamic> demo3(){
    return Future.delayed(Duration(seconds: 4), () {
      // throw ArgumentError("Error");
      return "hi world!";
    });
  }

  /// 返回错误
  Future<String> demo4(){
    return Future.error("error");
  }

  /// 内部执行错误,被捕获了,wait是无法检测到
  Future<void> demo5(){
    return Future.delayed(Duration(seconds: 4), () {
      throw ArgumentError("Error");
      // return "hi world!";
    }).catchError((e){
      //执行失败会走到这里
      print("内部捕获 $e");
    });
    // return Future.error("error");
  }

  /// 正常流程
  List<dynamic> list1 = [demo1(), demo2(), demo3()];
  /// 包含一个错误
  List<dynamic> list2 = [demo1(), demo2(), demo3(), demo4()];

  Future.wait<dynamic>([...list2]).then((value) => print(value)).catchError((e){
    //执行失败会走到这里
    print("失败了 $e");
  });
}

Async/Await

使用 async 和 await 的代码是异步的,但是看起来有点像同步代码。async能把普通函数变成异步函数。
Dart中的async/await 和JavaScript中的async/await功能和用法是几乎一样。

/// 定义Future函数
Future<String> checkVersion() async{
  return "1.2";
}
//先分别定义各个异步任务
Future<String> login(String userName, String pwd){
	...
    //用户登录
};
Future<String> getUserInfo(String id){
	...
    //获取用户信息 
};
Future saveUserInfo(String userInfo){
	...
	// 保存用户信息 
}; 

接下来,执行整个任务流:

login("alice","******").then((id){
 //登录成功后通过,id获取用户信息    
 getUserInfo(id).then((userInfo){
    //获取用户信息后保存 
    saveUserInfo(userInfo).then((){
       //保存用户信息,接下来执行其它操作
        ...
    });
  });
})

如果业务逻辑中有大量异步依赖的情况,过多的嵌套会导致的代码可读性下降以及出错率提高,并且非常难维护,也被叫做“回调地狱”。

使用async/await可以解决以上问题。

task() async {
   try{
    String id = await login("alice","******");
    String userInfo = await getUserInfo(id);
    await saveUserInfo(userInfo);
    //执行接下来的操作   
   } catch(e){
    //错误处理   
    print(e);   
   }  
}

  • async用来表示函数是异步的,定义的函数会返回一个Future对象,可以使用 then 方法添加回调函数。
  • await 后面是一个Future,表示等待该异步任务完成,异步完成后才会往下走;await必须出现在 async 函数内部。

Stream

官方文档-streams
Stream 是一系列异步事件的序列。上面的Future,是返回一个异步任务,那Stream就是可以串行返回多个异步任务。
Stream有两种类型,一种是点对点的单订阅流(Single-subscription),另一种则是广播流(Broadcast)。
主要作用是监听事件流,常作为事件总线使用。

单订阅流

单订阅流的特点是只允许存在一个监听器,即使该监听器被取消后,也不允许再次注册监听器。

广播流

这种流可以在同一时间设置多个不同的监听器同时监听,同时你也可以在取消上一个订阅后再次对其发起监听。

使用 StreamController 生成 Stream

创建Stream的方式有很多,跟Future类似

  1. 可以通过Stream提供的构造函数。
  2. Future可以使用async创建,那Stream就使用 async* 函数创建。
  3. 使用 StreamController 生成 Stream。Stream的一个帮助类,可用于整个 Stream 过程的控制。

这里介绍StreamController来创建Stream,这里就以广播流的形式来介绍一下。

void testStreamController(){
  /// 创建广播流
  /// onListen,有监听事件就回调
  /// onCancel,关闭stream事件流就回调
  StreamController<String> sc = StreamController<String>.broadcast(
      onListen: ()=>print("onListen"),
      onCancel: ()=>print("onCancel"),
  );

  /// 监听事件
  sc.stream.listen((String event){
    print("第一个监听 $event");
  });

  sc.stream.listen((String event){
    print("第二个监听 $event");
  });
  
  /// 放入事件
  sc.add('event1');
  // sc.add("event2");

  /// 关闭
  sc.close();
}

运行结果:

onListen
第一个监听 event1
第二个监听 event1
onCancel

Flutter中的EventBus的原理就是根据Stream实现。

Dart的不足

  1. Dart 不支持 protected,所以要么是 public,要么是 private,不能折中。
  2. 枚举不支持自定义值。只能从0开始。
  3. 场景应用少,还有待完善生态。

与Java对比

  1. 都是强类型语言。
  2. Java有public private protected这些访问修饰符,Dart的Class中属性默认public,若声明私有,只需在属性名前加_。
  3. Java用接口间接实现多继承,Dart提供更灵活的方式Mixin。
  4. 比java更适合函数式编程。

与js对比

  1. 都可以用在跨端实现上。
  2. js没用私有属性的概念;所有的属性都是公用的,Dart起码还可以使用_(下划线)表示私有。
  3. js弱语言,没有强制类型。仅在运行时发现错误。dart强类型。
  4. JavaScript具有庞大的社区和在线提供的出色框架。dart目前要考Flutter推广。

总结

主要介绍了dart的变量、函数、类、异步编程。今天课程主要是为打下个基础,学会这些内容基本就能满足基本的Flutter开发,学习以上内容后,推荐再去阅读官方的Dart语言规范和用法示例,能更好的配合团队使用Dart来开发项目。如下

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Flutter是Google开源的一款跨平台的UI开发框架,可以快速地构建高质量的移动、Web和桌面应用程序。而Embedded Linux是指Linux操作系统在嵌入式设备中的应用。通过将Flutter与Embedded Linux结合起来,可以让开发者在嵌入式设备上创建漂亮且功能强大的应用程序。 Flutter的跨平台特性使得开发者可以使用相同的代码库在多个平台上运行应用程序,包括嵌入式设备。嵌入式设备通常资源有限,但Flutter的轻量级和高性能使得它非常适合在此类设备上运行。Flutter的热重载功能可以让开发者快速迭代和测试应用程序,提高开发效率。 使用Flutter-Embedded Linux,开发者可以利用Flutter的丰富的UI组件和强大的渲染引擎来创建嵌入式设备上的用户界面。Flutter提供了丰富的UI控件和动画效果,可以实现各种视觉效果和交互体验。Flutter还具备良好的跨平台兼容性和高度定制性,可以适应不同嵌入式设备的各种需求。 除此之外,Flutter-Embedded Linux还提供了与Linux操作系统的良好集成,可以调用底层系统资源和API,如文件系统、网络接口等。这使得开发者可以通过Flutter在嵌入式设备上实现更强大的功能,例如与传感器的交互、与云服务的连接等。 总而言之,Flutter-Embedded Linux是一个强大的开发工具,可以帮助开发者在嵌入式设备中创建高质量的应用程序。它结合了Flutter的跨平台特性和Embedded Linux的优势,为开发者提供了更灵活、高效的开发环境。无论是工业控制、智能家居还是其他嵌入式应用,Flutter-Embedded Linux都能提供良好的开发体验和用户体验。 ### 回答2: Flutter-embedded-linux是指在嵌入式Linux平台上使用Flutter框架进行应用开发的一种技术方案。嵌入式Linux是指在资源有限的嵌入式设备上运行Linux操作系统的系统;而Flutter是一种跨平台的移动应用开发框架,可以同时在Android和iOS上运行。 使用Flutter-embedded-linux可以让开发者在嵌入式Linux平台上开发出跨平台的应用。这样一来,开发者不再需要针对不同的平台编写不同的代码,大大提高了开发效率。同时,Flutter的高性能和优秀的用户体验也被保留在嵌入式设备上。 在使用Flutter-embedded-linux时,开发者需要在嵌入式Linux平台上搭建Flutter的开发环境,包括安装Flutter SDK、配置相关的依赖库等。然后,可以使用Flutter提供的开发工具和API进行应用的开发和调试。 Flutter-embedded-linux可以应用于很多领域,例如智能家居、智能工业设备、嵌入式系统等。开发者可以利用Flutter-embedded-linux开发各种类型的应用,如物联网设备控制应用、工业监控系统、嵌入式音视频播放器等。 需要注意的是,由于嵌入式Linux平台的资源限制,开发者在使用Flutter-embedded-linux时需要特别关注应用的性能和资源消耗情况,避免出现过多的资源占用或性能瓶颈。 总之,Flutter-embedded-linux为开发者在嵌入式Linux平台上开发跨平台应用提供了一种方便、高效、高性能的技术方案,有望在嵌入式设备领域得到广泛应用。 ### 回答3: Flutter-Embedded-Linux是一种使用Flutter框架进行嵌入式开发的技术方案。Flutter是一种跨平台的开源UI框架,可以快速构建高性能、精美的应用程序。而Embedded-Linux则是嵌入式设备常用的操作系统。 通过将Flutter应用程序集成到Linux嵌入式系统中,可以在嵌入式设备上实现高效、流畅和美观的用户界面。Flutter的特点是能够在不同平台上保持一致的用户体验,因此在嵌入式系统上也能够实现类似于移动设备和桌面系统上的应用程序。 使用Flutter-Embedded-Linux进行嵌入式开发有一些优势。首先,Flutter具有快速构建UI界面的能力,可以节省开发时间。其次,Flutter对于动画和渲染效果的支持非常好,可以在嵌入式设备上实现更加流畅和绚丽的动画效果。此外,Flutter还支持热重载功能,可以实时更新应用程序而无需重新启动,极大地提高了开发效率。 然而,使用Flutter-Embedded-Linux也存在一些挑战。嵌入式设备通常资源有限,对占用内存和CPU的要求较高,需要对Flutter应用程序进行优化以提高性能。另外,由于Flutter是基于Dart语言开发的,需要事先熟悉Dart开发语言和Flutter框架的使用。 总之,Flutter-Embedded-Linux是一种用于嵌入式开发的技术方案,可以帮助开发者快速构建高品质的应用程序界面。它在嵌入式设备上的应用可以提供与移动设备和桌面系统相媲美的用户体验。但是,开发者需要注意对资源的合理利用和性能的优化,以确保应用程序在嵌入式设备上能够运行流畅。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值