Flutter里又一个非常重要的核心理念: 一切皆为组件, Flutter所有的元素皆由组件组成。比如: 一个布局元素,一个动画,一个装饰效果等。
Widget使用地址:https://github.com/nanos-11/Flutter_nan
简介:Widget是所有组件的基类 所有组件都继承自它
要想自定义组件必须继承下边两个类中的其中一个:
1️⃣ StatelessWidget:无状态组件,状态不可变。
2️⃣ StatefulWidget:有状态组件,持有的状态可能在widget生命周期改变。
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 Center(
child: new Text('Hello World'),
// child: new RandomWords(),
),
),
);
}
}
/*
* 添加一个有状态的部件
* @since 1.0.0
* @version code 1
* @author nan
*/
class RandomWords extends StatefulWidget {
@override
State createState() => new RandomWordsState();
}
// State 是当 Widget 被渲染或者在其生命周期中状态改变时,能同步读到相关信息的对象。
// 当实例StatefulWidget时必须保证能正确使用 State.setState 来告知该 Widget的状态发生了变化。
class RandomWordsState extends State<RandomWords> {
@override
Widget build(BuildContext context) {
final wordPair = new WordPair.random();
return new Text(wordPair.asPascalCase);
}
}
简介:MaterialApp是一个方便的widget,它封装了应用程序实现Material Design所需要的一个Widget。一般作为顶层的Widget用。
常用属性:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final wordPair = new WordPair.random();
return MaterialApp(
//在任务管理窗口中所显示的应用名字
title: 'Flutter Demo1',
// 应用的主要颜色值
color: Colors.blue,
// 应用各种 UI 所使用的主题颜色
theme: ThemeData(
primarySwatch: Colors.blueGrey,
),
// 应用默认所显示的界面 Widget
home: new Scaffold(
appBar: new AppBar(
title: new Text('Hello Flutter'),
),
body: new Center(
child: new Text(wordPair.asPascalCase),
),
),
);
}
}
简介:Scaffold是Material Design布局机构的基本实现,此类提供了用于显示drawer、snackbar和底部sheet的API 一般和MaterialApp一起使用。
常用属性:
appBar:显示在界面顶部的一个 AppBar
body:当前界面所显示的主要内容
floatingActionButton: 在 Material 中定义的一个功能按钮。
persistentFooterButtons:固定在下方显示的按钮。
drawer:侧边栏控件
bottomNavigationBar:显示在底部的导航栏按钮栏。可以查看文档:Flutter学习之制作底部菜单导航
backgroundColor:背景颜色
resizeToAvoidBottomPadding: 控制界面内容 body是否重新布局来避免底部被覆盖了,比如当键盘显示的时候,重新布局避免被键盘盖住内容。默认值为 true。
home: new Scaffold(
//显示在界面顶部的一个 AppBar
appBar: new AppBar(
title: new Text('Hello Flutter'),
),
//当前界面所显示的主要内容
body: new Center(
child: new Text(wordPair.asPascalCase),
),
// 在 Material 中定义的一个功能按钮
floatingActionButton: new FloatingActionButton(
onPressed: () {}, child: new Icon(Icons.add)),
//固定在下方显示的按钮。
persistentFooterButtons: <Widget>[
new FloatingActionButton(onPressed: () {}, child: new Icon(Icons.add)),
new FloatingActionButton(onPressed: () {}, child: new Icon(Icons.add)),
new FloatingActionButton(onPressed: () {}, child: new Icon(Icons.add)),
],
),
简介:Container是一个容器组件也叫布局组件(可以理解为前端的div,块级元素),负责布局、绘画、定位和大小
常用属性:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '容器组件示例',
home: Scaffold(
appBar: AppBar(
title: Text('容器组件示例'),
),
body: Center(
//添加容器
child: Container(
width: 200.0,
height: 200.0,
//添加边框装饰效果
decoration: BoxDecoration(
color: Colors.white,
//设置上下左右四个边框样式
border: new Border.all(
//边框颜色
color: Colors.grey,
//边框粗细
width: 8.0,
),
//边框的弧度
borderRadius: const BorderRadius.all(const Radius.circular(8.0)),
),
child: Text(
'Flutter',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 28.0),
),
),
),
),
);
}
}
简介:Text是文本组件,顾名思义Text组件就是用来显示一串文字的。
常用属性:
简介:Image是照片组件,顾名思义Image组件就是用来显示图形的组件。
常用属性:
注:Image组件引用本地图片方法
3️⃣:引用
//添加图片
child: Image.asset('images/ic_img_default.jpeg'),
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'images',
home: new Scaffold(
//显示在界面顶部的一个 AppBar
appBar: new AppBar(
title: new Text('images demo'),
),
//当前界面所显示的主要内容
body: new Center(
child: Image.asset('images/ic_img_default.jpg'),
),
),
);
}
}
图标组件(Icon)为展示图标的组件,该组件不可交互,要实现可交互的图标,可以考虑使用IconButton组件。
IconButton:可交互的Icon。
Icons:框架自带Icon集合。
IconTheme:Icon主题。
ImageIcon:通过AssetImages或者其他图片显示Icon。
常用属性
Center(
child: Container(
height: 120.0,
width: 120.0,
color: Colors.blue[50],
child: Align(
alignment: Alignment(0.2, 0.6),
//alignment: Alignment.topRight,
//alignment: FractionalOffset(0.2, 0.6),
child: FlutterLogo(
size: 60,
),
),
),
)
视频介绍地址:https://api.flutter.dev/flutter/widgets/Align-class.html
视频介绍地址:https://api.flutter.dev/flutter/widgets/AspectRatio-class.html
例如,如果您希望子级的最小高度为50.0逻辑像素,则可以将其const BoxConstraints(minHeight: 50.0)用作约束。
body: new ConstrainedBox(
constraints: const BoxConstraints(
minWidth: 100.0,
minHeight: 100.0,
maxWidth: 150.0,
maxHeight: 150.0,
),
child: new Container(
width: 400.0,
height: 400.0,
color: Colors.red,
),
),
地址:https://api.flutter.dev/flutter/widgets/ConstrainedBox-class.html
Column(
children: <Widget>[
Text('Deliver features faster'),
Text('Craft beautiful UIs'),
Expanded(
child: FittedBox(
fit: BoxFit.contain, // otherwise the logo will be tiny
child: const FlutterLogo(),
),
),
],
)
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('We move under cover and we move as one'),
Text('Through the night, we have one shot to live another day'),
Text('We cannot let a stray gunshot give us away'),
Text('We will fight up close, seize the moment and stay in it'),
Text('It’s either that or meet the business end of a bayonet'),
Text('The code word is ‘Rochambeau,’ dig me?'),
Text('Rochambeau!', style: DefaultTextStyle.of(context).style.apply(fontSizeFactor: 2.0)),
],
)
地址:https://api.flutter.dev/flutter/widgets/Column-class.html
使用Expanded窗口小部件可使Row,Column或Flex的子级 展开以填充主轴上的可用空间(例如,水平放置为Row或垂直放置为Column)。如果扩展了多个子项,则会根据伸缩因子在可用空间之间进行分配。
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Expanded Column Sample'),
),
body: Center(
child: Column(
children: <Widget>[
Container(
color: Colors.blue,
height: 100,
width: 100,
),
Expanded(
child: Container(
color: Colors.amber,
width: 100,
),
),
Container(
color: Colors.blue,
height: 100,
width: 100,
),
],
),
),
);
}
视频地址:https://api.flutter.dev/flutter/widgets/Expanded-class.html
最常用的网格布局是GridView.count和GridView.extent,它们创建一个在横轴上具有固定数量的图块的布局,而 GridView.extent创建一个具有最大横轴范围的图块的布局。自定义SliverGridDelegate可以生成子代的任意2D排列,包括未对齐或重叠的排列。
GridView.count(
primary: false,
padding: const EdgeInsets.all(20),
crossAxisSpacing: 10,
mainAxisSpacing: 10,
crossAxisCount: 2,
children: <Widget>[
Container(
padding: const EdgeInsets.all(8),
child: const Text('He\'d have you all unravel at the'),
color: Colors.teal[100],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Heed not the rabble'),
color: Colors.teal[200],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Sound of screams but the'),
color: Colors.teal[300],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Who scream'),
color: Colors.teal[400],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Revolution is coming...'),
color: Colors.teal[500],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Revolution, they...'),
color: Colors.teal[600],
),
],
)
本示例说明如何使用CustomScrollView和SliverGrid创建与上一个示例相同的网格。
CustomScrollView(
primary: false,
slivers: <Widget>[
SliverPadding(
padding: const EdgeInsets.all(20),
sliver: SliverGrid.count(
crossAxisSpacing: 10,
mainAxisSpacing: 10,
crossAxisCount: 2,
children: <Widget>[
Container(
padding: const EdgeInsets.all(8),
child: const Text('He\'d have you all unravel at the'),
color: Colors.green[100],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Heed not the rabble'),
color: Colors.green[200],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Sound of screams but the'),
color: Colors.green[300],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Who scream'),
color: Colors.green[400],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Revolution is coming...'),
color: Colors.green[500],
),
Container(
padding: const EdgeInsets.all(8),
child: const Text('Revolution, they...'),
color: Colors.green[600],
),
],
),
),
],
)
地址:https://api.flutter.dev/flutter/widgets/GridView-class.html
ListView(
padding: const EdgeInsets.all(8),
children: <Widget>[
Container(
height: 50,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 50,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
],
)
final List<String> entries = <String>['A', 'B', 'C'];
final List<int> colorCodes = <int>[600, 500, 100];
ListView.builder(
padding: const EdgeInsets.all(8),
itemCount: entries.length,
itemBuilder: (BuildContext context, int index) {
return Container(
height: 50,
color: Colors.amber[colorCodes[index]],
child: Center(child: Text('Entry ${entries[index]}')),
);
}
);
final List<String> entries = <String>['A', 'B', 'C'];
final List<int> colorCodes = <int>[600, 500, 100];
ListView.separated(
padding: const EdgeInsets.all(8),
itemCount: entries.length,
itemBuilder: (BuildContext context, int index) {
return Container(
height: 50,
color: Colors.amber[colorCodes[index]],
child: Center(child: Text('Entry ${entries[index]}')),
);
},
separatorBuilder: (BuildContext context, int index) => const Divider(),
);
地址:https://api.flutter.dev/flutter/widgets/ListView-class.html
Row(
children: <Widget>[
Expanded(
child: Text('Deliver features faster', textAlign: TextAlign.center),
),
Expanded(
child: Text('Craft beautiful UIs', textAlign: TextAlign.center),
),
Expanded(
child: FittedBox(
fit: BoxFit.contain, // otherwise the logo will be tiny
child: const FlutterLogo(),
),
),
],
)
地址: https://api.flutter.dev/flutter/widgets/Row-class.html
Stack(
children: <Widget>[
Container(
width: 100,
height: 100,
color: Colors.red,
),
Container(
width: 90,
height: 90,
color: Colors.green,
),
Container(
width: 80,
height: 80,
color: Colors.blue,
),
],
)
地址: https://api.flutter.dev/flutter/widgets/Stack-class.html
视频地址:https://api.flutter.dev/flutter/widgets/Wrap-class.html
视频地址:https://api.flutter.dev/flutter/widgets/Table-class.html