Fork me on GitHub

Hexo ~ 相关介绍 置顶

Hexo 命令

命令 命令说明
hexo new “My New Post” 创建文章
hexo server 启动服务
hexo generate 生成静态文件
hexo deploy hexo 部署
hexo clean hexo清理编译文件
hexo new page categories 创建分类
hexo new page tags 创建标签
hexo new page photos 创建相册
阅读更多...

Flutter ~ 如何优雅地使用新版enum功能

Dart 2.17 新增了一些enum的功能,一起来看看吧!

我也是看大佬 王叔不秃 学到的新姿势, 通过ChatGPT询问,给到的答案也通过switch来写对应方法来转换枚举。🤓

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void main() {
final p = PortType.fromString('USB-C');
print(p);
print(p.isUSB);
}

enum PortType {
usbA('USB-A', isUSB: true),
usbC('USB-C', isUSB: true),
lightning('LIGHTNING'),
unknown('UNKNOWN');

final String name;
final bool isUSB;

const PortType(this.name, {this.isUSB = false});

static PortType fromString(String name) {
return values.firstWhere((v) => v.name == name,
orElse: () => PortType.unknown);
}
}

注意事项:

最后一个枚举项后面的 "," 需要改成 ";" 否则无法通过编译。

Flutter ~ ThemeData通过ThemeExtension扩展自定义属性

ThemeExtensions 是在Flutter 3.0 中ThemeData类中新增的对象,通过它可以扩展自己想自定义的属性字段, Flutter 3.0之前需要编写一个扩展类来处理。

Flutter 3.0之前可以参考 在 flutter 中如何使用和扩展 ThemeData 这篇文章。

下面我们来介绍如果在Flutter 3.0中使用官方方法来扩展。

在ThemeData中 多了一个 final Map<Object, ThemeExtension> extensions 字段声明

要定义ThemeExtension扩展类,需要将一个或多个ThemeExtension子类传递给ThemeData.newcopyWith 的extensions属性。

要获取扩展名,请使用Theme.of(context).extension().

完整的Demo如下:

阅读更多...

Flutter ~ 编译禁用空安全

因为把pubspec.yaml文件environment的SDK版本进行了升级,导致一些第三方库报错不支持安全模式.

1
2
3
4
5
Waiting for connection from debug service on Chrome...
Error: Cannot run with sound null safety, because the following dependencies
don't support null safety:

- package:xxxx

Android 原生禁用空安全

在flutter工程中找到android目录下gradle.properties文件,添加 extra-front-end-options=--no-sound-null-safety

iOS 原生禁用空安全

Build Settings => User-Defined 添加 键 EXTRA_FRONT_END_OPTIONS ,值 --no-sound-null-safety

参考stackoverflow

阅读更多...

Flutter ~ AS设置常用的代码模版

我们在日常开发中,使用 Android Studio 新建的 dart 文件,里面没有任何代码,类名称都是需要自己在手动写上去,文件名和类名称还不一样,dart文件名是以 _ 来分割,类名称要遵循大驼峰命名法, 比较浪费时间,因此我们要使用代码模版来解决此问题。

比如:我们创建了一个 hello_test.dart 文件,dart代码内容 class HelloTest { }

1. 打开 File and Code Templates

Preferences > Editor > File and Code Templates

阅读更多...

Flutter ~ GZip解压缩

GZip最早由Jean-loup Gailly和Mark Adler创建,用于UNⅨ系统的文件压缩。我们在Linux中经常会用到后缀为.gz的文件,它们就是GZip格式的。现今已经成为Internet 上使用非常普遍的一种数据压缩格式,或者说一种文件格式

废话不多说,直接上代码。

代码运行示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void main() {
print("准备 GZip压缩");

//原始字符串
const testString = '测试一下GZip压缩字符串';
//GZip 压缩后的文本
final zipString = GzipUtil.gzipEncode(testString);

print("GZip 编码-$zipString");

//GZip 解压
final zipString2 = GzipUtil.gzipDecode(zipString);

print("GZip 解码-$zipString2");

}

工具类源码:

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
26
27
28
import 'dart:convert';
import 'dart:io';

class GzipUtil {
///GZIP 压缩
static String? gzipEncode(String? str) {
if (str == null) return str;
//先来转换一下
final stringBytes = utf8.encode(str);
//然后使用 gzip 压缩
final gzipBytes = GZipCodec().encode(stringBytes);
//然后再编码一下进行网络传输
final compressedString = base64UrlEncode(gzipBytes);
return compressedString;
}

///GZIP 解压缩
static String? gzipDecode(String? str) {
if (str == null) return str;
//先来解码一下
final List<int> stringBytes = base64Url.decode(str);
//然后使用 gzip 压缩
final gzipBytes = GZipCodec().decode(stringBytes);
//然后再编码一下
final compressedString = utf8.decode(gzipBytes);
return compressedString;
}
}

Flutter ~ Stack 组件

层叠布局和Web中的绝对定位、Android中的Frame布局是相似的,子组件可以根据距父容器四个角的位置来确定自身的位置。绝对定位允许子组件堆叠起来(按照代码中声明的顺序)。Flutter中使用StackPositioned这两个组件来配合实现绝对定位。Stack允许子组件堆叠,而Positioned用于根据Stack的四个角来确定子组件的位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/// Creates a stack layout widget.
///
/// By default, the non-positioned children of the stack are aligned by their
/// top left corners.
Stack({
Key? key,
this.alignment = AlignmentDirectional.topStart,
this.textDirection,
this.fit = StackFit.loose,
@Deprecated(
'Use clipBehavior instead. See the migration guide in flutter.dev/go/clip-behavior. '
'This feature was deprecated after v1.22.0-12.0.pre.'
)
this.overflow = Overflow.clip,
this.clipBehavior = Clip.hardEdge,
List<Widget> children = const <Widget>[],
})
  • alignment:此参数决定如何去对齐没有定位(没有使用Positioned)或部分定位的子组件。所谓部分定位,在这里特指没有在某一个轴上定位:leftright为横轴,topbottom为纵轴,只要包含某个轴上的一个定位属性就算在该轴上有定位。

  • textDirection:和RowWraptextDirection功能一样,都用于确定alignment对齐的参考系,即:textDirection的值为TextDirection.ltr,则alignmentstart代表左,end代表右,即从左往右的顺序;textDirection的值为TextDirection.rtl,则alignment的start代表右,end代表左,即从右往左的顺序。

  • fit:此参数用于确定没有定位的子组件如何去适应Stack的大小。StackFit.loose表示使用子组件的大小,StackFit.expand表示扩伸到Stack的大小。

  • overflow:此属性已经废弃,改换为clipBehavior。

  • clipBehavior:此属性决定裁剪方式。

clipBehavior属性值 说明
clipBehavior: Clip.none 不裁剪
clipBehavior: Clip.hardEdge 裁剪但不应用抗锯齿,裁剪速度比none模式慢一点,但比其他方式快。
clipBehavior: Clip.antiAlias 裁剪而且抗锯齿,以实现更平滑的外观。裁剪速度比antiAliasWithSaveLayer快,比hardEdge慢。
clipBehavior: Clip.antiAliasWithSaveLayer 带有抗锯齿的剪辑,并在剪辑之后立即保存saveLayer。

初探Stack组件的使用

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
26
27
28
29
30
31
32
33
34
35
36
37
import 'package:flutter/material.dart';

void main() {
runApp(
MaterialApp(title: 'Stack Demo', home: StackDemo()),
);
}

class StackDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Stack 组件'),
),
body: Stack(
children: <Widget>[
Container(
width: 100,
height: 100,
color: Colors.red,
),
Container(
width: 90,
height: 90,
color: Colors.blue,
),
Container(
width: 80,
height: 80,
color: Colors.green,
),
],
),
);
}
}

上面的代码Stack做为根布局,叠加的方式展示3个组件,第一个组件比较大100100,第二个组件稍微小点90**90

,第三个组件最小80*80,显示的方式是能看见第一个和第二个组件的部分区域,第三个组件是能全部显示出来

阅读更多...

Flutter ~ 小数取整的多种实现方式 & 保留小数点后 n 位

1. 舍弃小数部分(取整)

首先我们来看如何只保留整数位,这里有很多方法可以实现:

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
26
27
28
29
30
31
void main() {
double price = 100 / 3;

//原始值, 结果为 33.333333333333336。
print("price = $price");

//舍弃当前变量的小数部分,结果为 33。返回值为 int 类型。
print("price.truncate() = ${price.truncate()}");

//舍弃当前变量的小数部分,浮点数形式表示,结果为 33.0。返回值为 double。
print("price.truncateToDouble() = ${price.truncateToDouble()}");

//舍弃当前变量的小数部分,结果为 33。返回值为 int 类型。
print("price.toInt() = ${price.toInt()}");

//小数部分向上进位,结果为 34。返回值为 int 类型。
print("price.ceil() = ${price.ceil()}");

//小数部分向上进位,结果为 34.0。返回值为 double。
print("price.ceilToDouble() = ${price.ceilToDouble()}");

//当前变量四舍五入后取整,结果为 33。返回值为 int 类型。
print("price.round() = ${price.round()}");

//当前变量四舍五入后取整,结果为 33.0。返回值为 double 类型。
print("price.roundToDouble() = ${price.roundToDouble()}");

//取整: 忽略小数位,返回int整数,结果为 33。
final int number = 100 ~/ 3;
print("number = $number");
}
阅读更多...

Flutter ~ Dart运算符

1.Dart在线编辑器

Dart 运算符和绝大部分编程语言的运算符一样,所以你可以用熟悉的方式去执行程序代码运算。

2.运算符

?. 运算符

它的意思是左边如果为空返回 null,否则返回右边的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void main() {
Animal animal = new Animal('cat');
Animal empty = null;

//animal 非空,返回 animal.name 的值 cat
print(animal?.name);
//empty 为空,返回 null
print(empty?.name);

//animal 非空,可以直接访问 animal.name 的值 cat
print(animal.name);
//empty 为空,抛出异常
print(empty.name);
}

class Animal {
final String name;
Animal(this.name);
}
阅读更多...
  • Copyrights © 2012-2022 Soto Pu

请我喝杯咖啡吧~

支付宝
微信