只不过是一只脚放到另一只脚前面。但我一直很惊讶这些原本是本能的事实际做起来有多困难。
Widget
Flutter中几乎所有的对象都是一个Widget,与原生开发中“控件”不同的是,Flutter中的widget的概念更广泛,它不仅可以表示UI元素,也可以表示一些功能性的组件如:用于手势检测的 GestureDetector widget、用于应用主题数据传递的Theme等等。而原生开发中的控件通常只是指UI元素。
lib/main.dart 文件入口
启动项目
flutter run
hot reload 及时更新
- 命令行 r
- vscode 有调试工具,文件记得保存就行了
父级组件
- StatelessWidget 无状态widget,类似静态页面,不与用户交互
- StatefulWidget 有状态widget,可以改变,可以与用户交互
常用基础widget
- Text:该 widget 可让您创建一个带格式的文本。
- Row、 Column: 这些具有弹性空间的布局类Widget可让您在水平(Row)和垂直(Column)方向上创建灵活的布局。其设计是基于web开发中的Flexbox布局模型。
- Stack: 取代线性布局 (译者语:和Android中的FrameLayout相似),Stack允许子 widget 堆叠, 你可以使用 Positioned 来定位他们相对于Stack的上下左右四条边的位置。Stacks是基于Web开发中的绝对定位(absolute positioning )布局模型设计的。
- Container: Container 可让您创建矩形视觉元素。container 可以装饰一个BoxDecoration, 如 background、一个边框、或者一个阴影。 Container 也可以具有边距(margins)、填充(padding)和应用于其大小的约束(constraints)。另外, Container可以使用矩阵在三维空间中对其进行变换。
- Image 显示图片,可以加载本地资源、file、网络图片、内存图片
- TextField 输入框,类似于EditText
详解
Text
- 继承关系
Object > Diagnosticable > DiagnosticableTree > Widget > StatelessWidget > Text
创建Text
- new Text() 构造方法创建,只能生成一种style
- Text.rich() 静态方法创建,能够生成多种style
- new RichText() 与Text.rich()一样
在编辑器vscode上 widget Text ctrl+左击,都可以看见如下定义
Text()
const Text(
this.data, {
Key key,
this.style,
this.strutStyle,
this.textAlign,
this.textDirection,
this.locale,
this.softWrap,
this.overflow,
this.textScaleFactor,
this.maxLines,
this.semanticsLabel,
}) : assert(
data != null,
'A non-null String must be provided to a Text widget.',
),
textSpan = null,
super(key: key);
/// Creates a text widget with a [TextSpan].
///
/// The [textSpan] parameter must not be null.
const Text.rich(
this.textSpan, {
Key key,
this.style,
this.strutStyle,
this.textAlign,
this.textDirection,
this.locale,
this.softWrap,
this.overflow,
this.textScaleFactor,
this.maxLines,
this.semanticsLabel,
}) : assert(
textSpan != null,
'A non-null TextSpan must be provided to a Text.rich widget.',
),
data = null,
super(key: key);
常用Text属性案例
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Welcome to Flutter',
home: new Scaffold(
appBar: new AppBar(
title: new Text('Welcome to Flutter'),
),
body: new Column(
children: <Widget>[
Text(
"只不过是一只脚放到另一只脚前面。但我一直很惊讶这些原本是本能的事实际做起来有多困难。" * 20,
textAlign: TextAlign.end,
maxLines: 6, //最大行数
textScaleFactor: 2,//文本字体的缩放倍数,
style: new TextStyle(
decorationColor: const Color(0xffffffff), //线的颜色
decoration: TextDecoration.underline, //none无文字装饰 lineThrough删除线 overline文字上面显示线 underline文字下面显示线
decorationStyle: TextDecorationStyle.solid, //文字装饰的风格 dashed,dotted虚线(简短间隔大小区分) double三条线 solid两条线
wordSpacing: 1.0, //单词间隙(负值可以让单词更紧凑)
letterSpacing: 1.0, //字母间隙(负值可以让字母更紧凑)
fontStyle: FontStyle.italic, //文字样式,斜体和正常
fontSize: 14.0, //字体大小
fontWeight: FontWeight.w900, //字体粗细 粗体和正常
color: Colors.red, //文字颜色
),
),
],
)),
);
}
}
TextSpan
TextSpan跟Text的区别就在于TextSpan是分片,我们可以把一串字符串分为几个片段来管理,每个片段可以单独设置样式。
class TextSpan extends DiagnosticableTree {
/// Creates a [TextSpan] with the given values.
///
/// For the object to be useful, at least one of [text] or
/// [children] should be set.
const TextSpan({
this.style,
this.text,
this.children,
this.recognizer,
this.semanticsLabel,
});
其中style 跟上面的Text的style一致,用来设置样式,text就是要显示的文本内容。 children是一个TextSpan的数组,不能为空,recognizer是用来处理手势的
Text.rich(
TextSpan(
children:[
TextSpan(
text: "网址",
style: TextStyle(
color: Colors.black,
fontSize: 24,
)
),
TextSpan(
text: 'www.baidu.com',
style:TextStyle(
color: Colors.blue,
fontSize: 20,
fontStyle: FontStyle.italic,
)
)
]
)
)
案例总结
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Welcome to Flutter',
home: new Scaffold(
appBar: new AppBar(
title: new Text('Welcome to Flutter'),
),
body: new Column(
children: <Widget>[
Text(
"只不过是一只脚放到另一只脚前面。但我一直很惊讶这些原本是本能的事实际做起来有多困难。" * 20,
textAlign: TextAlign.end,
maxLines: 6, //最大行数
textScaleFactor: 2,//文本字体的缩放倍数,
style: new TextStyle(
decorationColor: const Color(0xffffffff), //线的颜色
decoration: TextDecoration.underline, //none无文字装饰 lineThrough删除线 overline文字上面显示线 underline文字下面显示线
decorationStyle: TextDecorationStyle.solid, //文字装饰的风格 dashed,dotted虚线(简短间隔大小区分) double三条线 solid两条线
wordSpacing: 1.0, //单词间隙(负值可以让单词更紧凑)
letterSpacing: 1.0, //字母间隙(负值可以让字母更紧凑)
fontStyle: FontStyle.italic, //文字样式,斜体和正常
fontSize: 14.0, //字体大小
fontWeight: FontWeight.w900, //字体粗细 粗体和正常
color: Colors.red, //文字颜色
),
),
Text.rich(
TextSpan(
children:[
TextSpan(
text: "网址",
style: TextStyle(
color: Colors.black,
fontSize: 24,
)
),
TextSpan(
text: 'www.baidu.com',
style:TextStyle(
color: Colors.blue,
fontSize: 20,
fontStyle: FontStyle.italic,
)
)
]
)
)
],
)),
);
}
}