一起来学习跨平台 UI 框架 Flutter 的常用布局组件
wptr33 2024-12-13 16:35 26 浏览
Flutter 常用布局组件
Flutter 控件本身通常由许多小型、单用途的控件组成,结合起来产生强大的效果,例如:Container 是一种常用的控件,由负责布局、绘画、定位和大小调整的几个控件组成
具体来说:Container 是由 LimitedBox、ConstrainedBox、 Align、Padding、DecoratedBox 和 Transform 控件组成,而不是将 Container 子类化来产生自定义效果,您可以用这种新颖的方式组合这些以及其他简单的控件
类的层次结构是扁平的,以最大化可能的组合数量
在写应用程序时,经常会使用 StatelessWidget 和 StatefulWidget 编写新控件,两者的差别在于你是否要管理控件的状态;一个控件的主要任务是实现 build 函数,定义控件中其他较低层次的控件;build 函数将依次构建这些控件,直到底层渲染对象
基本组件
Container
容器,一个常用的控件,由基本的绘制、位置和大小控件组成;负责创建矩形的可视元素,可以用 BoxDecoration 来设计样式,比如背景、边框和阴影,Container 也有边距、填充和大小限制,另外,还可以在三维空间利用矩阵进行变换
没有子控件的容器尽可能大,除非传入的大小约束是无限的,在这种情况下,它们尽可能小。有子控件的容器将自己的尺寸给他们的孩子。我们可以通过 width、height 和 constraints 属性控制 size
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n12" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> 1 new Container(
2 constraints: new BoxConstraints.expand(
3 height: Theme.of(context).textTheme.display1.fontSize * 1.1 + 200.0,
4 ),
5 padding: const EdgeInsets.all(8.0),
6 color: Colors.teal.shade700,
7 alignment: Alignment.center,
8 child: new Text('Hello World', style: Theme.of(context).textTheme.display1.copyWith(color: Colors.white)),
9 foregroundDecoration: new BoxDecoration(
10 image: new DecorationImage(
11 image: new NetworkImage('https://www.example.com/images/frame.png'),
12 centerSlice: new Rect.fromLTRB(270.0, 180.0, 1360.0, 730.0),
13 ),
14 ),
15 transform: new Matrix4.rotationZ(0.1),
16 )</pre>
Row
flex 水平布局控件,能够将子控件水平排列,是基于 Web 的 flexbox 的布局模式设计的
Row 子控件有灵活与不灵活的两种,Row 首先列出不灵活的子控件,减去它们的总宽度,计算还有多少可用的空间。然后Row 按照 Flexible.flex 属性确定的比例在可用空间中列出灵活的子控件。要控制灵活子控件,需要使用 Expanded 控件
注意该控件不支持滑动,如果子控件超过剩余空间,会报错,如果想支持水平滑动,考虑使用 ListView
如果只有一个子控件,可以使用 Align or Center控件定义该子控件位置
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n22" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> 1 new Row(
2 children: <Widget>[
3 new Expanded(
4 child: new Text('Deliver features faster', textAlign: TextAlign.center),
5 ),
6 new Expanded(
7 child: new Text('Craft beautiful UIs', textAlign: TextAlign.center),
8 ),
9 new Expanded(
10 child: new FittedBox(
11 fit: BoxFit.contain, // otherwise the logo will be tiny
12 child: const FlutterLogo(),
13 ),
14 ),
15 ],
16 )</pre>
Column
flex 垂直布局控件,能够将子控件垂直排列
用法与 Row 控件一样
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n29" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> 1 new Column(
2 crossAxisAlignment: CrossAxisAlignment.start,
3 mainAxisSize: MainAxisSize.min,
4 children: <Widget>[
5 new Text('We move under cover and we move as one'),
6 new Text('Through the night, we have one shot to live another day'),
7 new Text('We cannot let a stray gunshot give us away'),
8 new Text('We will fight up close, seize the moment and stay in it'),
9 new Text('It’s either that or meet the business end of a bayonet'),
10 new Text('The code word is ‘Rochambeau,’ dig me?'),
11 new Text('Rochambeau!', style: DefaultTextStyle.of(context).style.apply(fontSizeFactor: 2.0)),
12 ],
13 )</pre>
Image
显示图像的控件,Image 控件有多种构造函数:
- new Image,用于从 ImageProvider 获取图像
- new Image.asset,用于使用 key 从 AssetBundle 获取图像
- new Image.network,用于从 URL 地址获取图像
- new Image.file,用于从 File 获取图像
为了自动执行像素密度感知资源分辨率,使用 AssetImage 指定图像,需要确保在控件树中的图片控件上方存在 MaterialApp、WidgetsApp 和 MediaQuery 控件
不同的手机有不同的像素比率,这时就需要根据手机的像素比率来加载不同图片,做法很简单,只需要在图片同级目录下创建 2.0x/… 和 3.0x/… 的目录就可以了
我们在 pubspec.yaml 这个文件里指定本地图片路径
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n46" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"># To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg</pre>
Text
用来显示文本的控件
下面的实例有7个不同样式的文本控件:
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n52" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> 1 import 'package:flutter/material.dart';
2 class TextDemo extends StatelessWidget {
3 @override
4 Widget build(BuildContext context) {
5 return new Scaffold(
6 appBar: new AppBar(
7 title: new Text('文本控件'),
8 ),
9 body: new Column(
10 children: <Widget>[
11 new Text(
12 '红色+黑色删除线+25号',
13 style: new TextStyle(
14 color: const Color(0xffff0000),
15 decoration: TextDecoration.lineThrough,
16 decorationColor: const Color(0xff000000),
17 fontSize: 25.0,
18 ),
19 ),
20 new Text(
21 '橙色+下划线+24号',
22 style: new TextStyle(
23 color: const Color(0xffff9900),
24 decoration: TextDecoration.underline,
25 fontSize: 24.0,
26 ),
27 ),
28 new Text(
29 '虚线上划线+23号+倾斜',
30 style: new TextStyle(
31 decoration: TextDecoration.overline,
32 decorationStyle: TextDecorationStyle.dashed,
33 fontSize: 23.0,
34 fontStyle: FontStyle.italic,
35 ),
36 ),
37 new Text(
38 'serif字体+24号',
39 style: new TextStyle(
40 fontFamily: 'serif',
41 fontSize: 26.0,
42 ),
43 ),
44 new Text(
45 'monospace字体+24号+加粗',
46 style: new TextStyle(
47 fontFamily: 'monospace',
48 fontSize: 24.0,
49 fontWeight: FontWeight.bold,
50 ),
51 ),
52 new Text(
53 '天蓝色+25号+2行跨度',
54 style: new TextStyle(
55 color: const Color(0xff4a86e8),
56 fontSize: 25.0,
57 height: 2.0,
58 ),
59 ),
60 new Text(
61 '24号+2个字母间隔',
62 style: new TextStyle(
63 fontSize: 24.0,
64 letterSpacing: 2.0,
65 ),
66 ),
67 ]
68 ),
69 );
70 }
71 }
72 void main() {
73 runApp(
74 new MaterialApp(
75 title: 'Flutter教程',
76 home: new TextDemo(),
77 ),
78 );
79 }</pre>
Icon
- 图标控件,按照IconData中所描述的规则绘制,如Material中预定义的IconDatas
- 该控件不可交互,要实现可交互的图标,可以考虑使用Material中的 IconButton
- 该控件必须在 Directionality控件里使用,通常这是由 WidgetsApp 或 MaterialApp 自动引入的
RaisedButton
Material Design 风格的浮动按钮,以方形纸片样式悬停在界面上,点击后会产生墨水扩散效果。
避免在 dialog 和 card 控件里使用,一般弹出式的控件建议使用扁平化按钮,减少布局层次叠加
使用时,要实现 onPressed 回调方法,否则按钮处于禁用状态,默认显示 disabledColor 样式的扁平化按钮,并且此时更改按钮的颜色不会生效
- 注意该控件的父控件必须是 Material 控件
- 如果你只需要点击后产生墨水扩散效果,但不想使用按钮,请考虑直接使用 InkWell 控件
- 如有必要,该按钮将拉伸以适应子控件大小
Scaffold
Scaffold 实现了基本的Material Design布局结构;也就是说, MaterialApp 的 child 是 Scaffold Widget
在 Material 设计中定义的单个界面上的各种布局元素,在 Scaffold 中都有支持,比如 左边栏(Drawers)、snack bars、以及 bottom sheets
Scaffold 有下面几个主要属性:
- appBar:显示在界面顶部的一个 AppBar,也就是 Android 中的 ActionBar 、Toolbar
- body:当前界面所显示的主要内容 Widget
- floatingActionButton:Material设计中所定义的 FAB,界面的主要功能按钮
- persistentFooterButtons:固定在下方显示的按钮,比如对话框下方的确定、取消按钮
- drawer:侧边栏控件
- backgroundColor: 内容的背景颜色,默认使用的是 ThemeData.scaffoldBackgroundColor 的值
- bottomNavigationBar: 显示在页面底部的导航栏
- resizeToAvoidBottomPadding:类似于 Android 中的 android:windowSoftInputMode=”adjustResize”,控制界面内容 body 是否重新布局来避免底部被覆盖了,比如当键盘显示的时候,重新布局避免被键盘盖住内容。默认值为 true
显示 snackbar 或者 bottom sheet 的时候,需要使用当前的 BuildContext 参数调用 Scaffold.of 函数来获取 ScaffoldState 对象,然后使用 ScaffoldState.showSnackBar 和 ScaffoldState.showBottomSheet 函数来显示
要特别注意 Scaffold.of 的参数 BuildContext, 如果包含该 BuildContext 的 Widget 是 Scaffold 的父 Widget,则 Scaffold.of 是无法查找到对应的 ScaffoldState 对象的,Scaffold.of 返回的是父对象中最近的 Scaffold 中的 ScaffoldState 对象
比如,如果在 Scaffold 的 build 函数中,使用 build 的 BuildContext 参数是可以的:
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n95" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> 1 @override
2 Widget build(BuildContext context) {
3 return new RaisedButton(
4 child: new Text('SHOW A SNACKBAR'),
5 onPressed: () {
6 Scaffold.of(context).showSnackBar(new SnackBar(
7 content: new Text('Hello!'),
8 ));
9 },
10 );
11 }</pre>
如果 build 函数返回一个 Scaffold 对象,则由于 Scaffold 对象是这个 Widget 的子对象,所以使用这个 build 的 BuildContext 参数是不能查找到 ScaffoldState 对象的
这个时候,通过在 Scaffold 中使用一个 Builder 来提供一个新的 BuildConext :
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n101" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"> 1 @override
2 Widget build(BuildContext context) {
3 return new Scaffold(
4 appBar: new AppBar(
5 title: new Text('Demo')
6 ),
7 body: new Builder(
8 // Create an inner BuildContext so that the onPressed methods
9 // can refer to the Scaffold with Scaffold.of().
10 builder: (BuildContext context) {
11 return new Center(
12 child: new RaisedButton(
13 child: new Text('SHOW A SNACKBAR'),
14 onPressed: () {
15 Scaffold.of(context).showSnackBar(new SnackBar(
16 content: new Text('Hello!'),
17 ));
18 },
19 ),
20 );
21 },
22 ),
23 );
24 }</pre>
另外还可以把 build 函数中的 Widget 分别创建,分别引入新的 BuildContext 来获取 Scaffold
结语
至此,我们今天关于 Flutter 框架 中的常用布局组件就介绍到这里了;希望以上的内容能够对大家有所帮助,关于 Flutter 的相关技术问题,我们还要去好好的学习剖析;因此我把工作中遇到的 Flutter 组件开源库相关问题,以及对网上大部分的资料的收集和整理,最终整合出了一份 《Flutter 高级开发学习手册》
有需要这份学习手册的朋友,可以私信发送“手册”即可 免费获取;希望大家通过阅读这份学习手册,能够查漏补缺;早日精通 Flutter
Flutter 编程原理
Flutter3.3 项目实战
文章篇幅有限;手册内容就不完全展示了,有需要的小伙伴可以私信发送“手册”,即可 免费获取
资料整理不易,如果觉得内容对你有所帮助的话,可以点赞转发分享一下哦~
最后祝各位开发者早日精通 Flutter ,攀登上更高的高峰
相关推荐
- MYSQL术语介绍:dynamic row format
-
InnoDB行格式。因为可变长度列值存储在保存行数据的页面之外,所以对于包含大对象的行非常有效。由于通常不会访问大字段来评估查询条件,因此不会经常将它们带入缓冲池,从而减少I/O操作并更好地利用缓...
- 阿里面试:MySQL Binlog有哪些格式?底层原理?优缺点?
-
binlog的格式也有三种:STATEMENT、ROW、MIXED,下面我详解binlog三种模式@mikechenStatement模式Statement模式:是基于SQL语句的复制(statem...
- Mysql日期格式化显示“年月”(mysql日期格式化)
-
数据库中存储格式为DATE,如果只显示年月,就需要将日期数据格式化。下面通过两种方式对其格式化显示:...
- 看完这篇还不懂 MySQL 主从复制,可以回家躺平了
-
我们在平时工作中,使用最多的数据库就是MySQL...
- MySQL binlog format (Statement、Row、Mixed) 二进制日志格式
-
MySQL的binlog日志作用是用来记录MySQL内部增删改查等对MySQL数据库有更新的内容的记录(对数据库的改动),对数据库的查询select或show等不会被binlog日志记录,主要用于数据...
- 性能优化-界面卡顿和丢帧(Choreographer 代码检测)
-
标签:ChoreographerUI卡顿UI丢帧本文将介绍3个知识点:获取系统UI刷新频率检测UI丢帧和卡顿输出UI丢帧和卡顿堆栈信息...
- 使用Java分析器优化代码性能,解决OOM问题
-
背景最近我一直在做性能优化,对一个单机应用做性能优化。主要是涉及到解析和导入导出相关的业务。大致说一下这个单机应用干嘛的:制作票样,类似于答题卡。发给某些人填写,然后通过单机python图像识别存到数...
- 面试必问的HashCode技术内幕(hashmap面试题原理)
-
3hashCode的内幕tips:面试常问/常用/常出错...
- 实战Netty!基于私有协议,怎样快速开发网络通信服务
-
私有协议编写目的本文档用于描述边缘计算单元(以下简称边缘盒)与上位机配置软件(以下简称上位机)之间进行的数据交互通信协议。通信方式...
- C#工控上位机系列(2)- 串口通信/监控工具
-
工控机通常都带有很多串口(10个),而且可以通过Moxa卡扩展串口.但Moxa的串口和电脑自带的串口还是有点区别C#里面没区别,但之前VB6的MSComm控件有时就会有不一样的地方.支持串口通讯...
- Java加密与解密之消息摘要算法1(消息摘要(hash函数编码法),又称数字指纹 ( ))
-
消息摘要算法有3大类,分别是:MD、SHA、MAC,通常用于数据完整性的验证。MD:MessageDigest消息摘要算法。包括:MD2,MD4,MD53种算法。SHA:SecureHashA...
- zookeeper的Leader选举源码解析(zookeeper角色选举角色包括)
-
作者:京东物流梁吉超zookeeper是一个分布式服务框架,主要解决分布式应用中常见的多种数据问题,例如集群管理,状态同步等。为解决这些问题zookeeper需要Leader选举进行保障数据的强一致...
- Java 中五种最常见加密算法:原理、应用与代码实现
-
引言在现代软件开发中,数据安全至关重要。无论是用户密码存储、敏感信息传输,还是系统间的通信,加密技术都扮演着核心角色。Java作为广泛使用的编程语言,通过javax.crypto和java.s...
- 干货|6招学会调用NFC的各个功能(调出nfc)
-
现在越来越多的手机支持NFC功能,这种轻松、安全、迅速的通信的无线连接技术,能够让我们的手机替代门禁卡、公交卡、银行卡甚至是车钥匙,那么怎么让APP中能够调用这个功能呢?今天小编就来教给大家!...
- 一文读懂流媒体协议之RTP 协议(rtp流媒体服务器)
-
一、简介1.1RTPRTP全名是Real-timeTransportProtocol(实时传输协议)。它是IETF提出的一个标准,对应的RFC文档为RFC3550(RFC1889为其过期版本)。...
- 一周热门
-
-
C# 13 和 .NET 9 全知道 :13 使用 ASP.NET Core 构建网站 (1)
-
因果推断Matching方式实现代码 因果推断模型
-
git pull命令使用实例 git pull--rebase
-
面试官:git pull是哪两个指令的组合?
-
git 执行pull错误如何撤销 git pull fail
-
git pull 和git fetch 命令分别有什么作用?二者有什么区别?
-
git fetch 和git pull 的异同 git中fetch和pull的区别
-
git pull 之后本地代码被覆盖 解决方案
-
还可以这样玩?Git基本原理及各种骚操作,涨知识了
-
git命令之pull git.pull
-
- 最近发表
-
- MYSQL术语介绍:dynamic row format
- 阿里面试:MySQL Binlog有哪些格式?底层原理?优缺点?
- Mysql日期格式化显示“年月”(mysql日期格式化)
- 看完这篇还不懂 MySQL 主从复制,可以回家躺平了
- MySQL binlog format (Statement、Row、Mixed) 二进制日志格式
- 性能优化-界面卡顿和丢帧(Choreographer 代码检测)
- 使用Java分析器优化代码性能,解决OOM问题
- 面试必问的HashCode技术内幕(hashmap面试题原理)
- 实战Netty!基于私有协议,怎样快速开发网络通信服务
- C#工控上位机系列(2)- 串口通信/监控工具
- 标签列表
-
- git pull (33)
- git fetch (35)
- mysql insert (35)
- mysql distinct (37)
- concat_ws (36)
- java continue (36)
- jenkins官网 (37)
- mysql 子查询 (37)
- python元组 (33)
- mybatis 分页 (35)
- vba split (37)
- redis watch (34)
- python list sort (37)
- nvarchar2 (34)
- mysql not null (36)
- hmset (35)
- python telnet (35)
- python readlines() 方法 (36)
- munmap (35)
- docker network create (35)
- redis 集合 (37)
- python sftp (37)
- setpriority (34)
- c语言 switch (34)
- git commit (34)