Text组件
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: "TestFlutter",
home: new Scaffold(
appBar: AppBar(
title: new Text("TestFlutter"),
),
body: Center(
child: Text(
"这是text组件,了解它的个性吧,阿斯顿法国红酒快乐立刻就会功夫的撒请问认同与 i 哦哦擗来看看就会更广泛的撒",
textAlign: TextAlign.center, //设置文本对齐方式。居中,居左,居右
maxLines: 1, //最多显示1行
// overflow: TextOverflow.fade, //文字从上到下有渐变效果
// overflow: TextOverflow.clip, //多余部分直接切割了,没有...
overflow: TextOverflow.ellipsis, //多余的部分以...结尾
style: TextStyle(
fontSize: 35, //设置文本字体大小,可以使用小数25.0这样
// color: Colors.pink //设置文本的颜色,这个是使用Colors,
color: Color.fromARGB(255, 255, 125, 125), //设置文本的颜色,这里使用RGB设置,
decoration: TextDecoration.underline, //文本加下划线
decorationColor: Colors.black, //下划线颜色
decorationStyle: TextDecorationStyle.double, //下划线的样式,双下划线,还有虚线,实线
),
),
),
),
);
}
}
TextSpan 富文本
import "package:flutter/material.dart";
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
TextStyle blackStyle = TextStyle(fontWeight: FontWeight.normal, fontSize: 20, color: Colors.black); // 黑色样式
TextStyle redStyle = TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: Colors.red); // 红色样式
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "TextSpan",
home: Scaffold(
appBar: AppBar(title: Text("TextSpan富文本"),),
body: Text.rich(
TextSpan(
children: <TextSpan>[
TextSpan(text:'文本是视图系统中常见的控件,它用来显示一段特定样式的字符串,类似', style: redStyle), // 第 1 个片段,红色样式
TextSpan(text:'Android', style: blackStyle), // 第 1 个片段,黑色样式
TextSpan(text:'中的', style:redStyle), // 第 1 个片段,红色样式
TextSpan(text:'TextView', style: blackStyle) // 第 1 个片段,黑色样式
]
),
),
),
);
}
}
Image组件
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: "TestFlutter",
home: new Scaffold(
appBar: AppBar(
title: new Text("TestFlutter"),
),
body: Center(
child: Container(
/**
* 在Container中添加Image组件
* asset,如 Image.asset(‘images/logo.png’);
* file 加载本地(File 文件)图片,如 Image.file(new File(’/storage/xxx/xxx/test.jpg’));
* network 网络图片 如 Image.network('http://xxx/xx.png');
*/
child: Image.network(
"https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2884107401,3797902000&fm=26&gp=0.jpg",
// width: 400, //设置图片的宽
// height: 200, //设置图片的高
/**
* 设置图片的模式
* BoxFit.contain 保证图片不拉伸的情况下充满容器
* BoxFit.fill 充满容器,会拉伸图片
* BoxFit.fitWidth 图片的宽度填满,会剪切图片
* BoxFit.fitHeight 图片的高度填满,宽度会留有空隙
* BoxFit.cover 图片不变形填满,会裁切图片,保留图片的中心范围
* BoxFit.scaleDown 以图片原先大小显示
* BoxFit.none
*/
fit: BoxFit.contain,
color: Colors.pink, //设置图片的颜色
colorBlendMode: BlendMode.darken, //混合模式,和color一起使用显示整个图片是color,有许多模式
/**
* ImageRepeat.repeatX 父容器横向图片重复
* ImageRepeat.repeatY 父容器纵向图片重复
*/
repeat: ImageRepeat.repeat, //重复模式,图片重复填满父容器,
),
width: 400, //设置Container宽度
height: 200, //设置Container高度
color: Colors.pink,//在不设置Container的宽高的情况下,Container会随子控件的高度变化而变化
),
),
),
);
}
}
FadeInImage 可以使用占位图的控件
import "package:flutter/material.dart";
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "TextSpan",
home: Scaffold(
appBar: AppBar(title: Text("TextSpan富文本"),),
body: FadeInImage.assetNetwork(
placeholder: "assets/loading.gif",//在网络图片未加载出来之前,使用本地图片做占位图,支持gif
image: "https://*****/****.png",
fit: BoxFit.cover,
width: 200,
height: 200,
)
),
);
}
}
CachedNetworkImage 一个网络图片缓存的三方
和FadeInImage类似,但是比它更强大
CachedNetworkImage(
imageUrl: "http://xxx/xxx/jpg",
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error), //提供如果图片加载出错,使用备用图片
)
Button 按钮
有3种样式
FloatingActionButton
:圆形button
RaisedButton
:凸起的按钮,默认带有灰色背景,被点击后灰色背景会加深。
FlatButton
:扁平化的按钮,默认透明背景,被点击后会呈现灰色背景。
import "package:flutter/material.dart";
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "TextSpan",
home: Scaffold(
appBar: AppBar(title: Text("TextSpan富文本"),),
body: Column(
children: <Widget>[
FloatingActionButton( //圆形button
onPressed: (){ //按钮响应方法
print("这是FloatingActionButton");
},
child: Text("FloatingActionButton"), //按钮文本,接收任意的widget,也可以设置image
),
RaisedButton( //凸起的按钮,默认带有灰色背景,被点击后灰色背景会加深。
onPressed: (){ //按钮响应方法
print("这是RaisedButton");
},
child: Text("RaisedButton"), //按钮文本,接收任意的widget,也可以设置image
),
FlatButton( //扁平化的按钮,默认透明背景,被点击后会呈现灰色背景。
onPressed: (){ //按钮响应方法
print("这是FlatButton");
},
child: Text("FlatButton"), //按钮文本,接收任意的widget,也可以设置image
),
FlatButton( //自定义样式的button
color: Colors.lightBlue, // 设置背景色为亮蓝色
shape:BeveledRectangleBorder(borderRadius: BorderRadius.circular(20.0)), // 设置斜角矩形边框
colorBrightness: Brightness.light, // 确保文字按钮为深色
onPressed: () => print('FlatButton pressed'), //按钮响应方法
child: Row(children: <Widget>[Icon(Icons.add), Text("Add")],) //按钮上的widget,接收任意的widget
),
],
)
),
);
}
}
ListView组件(相当于iOS中的tableview和scrollview)
ListView 提供了一个默认构造函数 ListView
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "ListView",
home: Scaffold(
appBar: AppBar(
title: Text("ListView"),
),
body: ListView( //相当于iOS中的tableview
children: <Widget>[
ListTile(leading: Icon(Icons.map),title: Text("地图"),), //ListTile 是 Flutter 提供的用于快速构建列表项元素的小组件单元,相当于tableviewcell
ListTile(leading: Icon(Icons.phone),title: Text("手机"),), //第二行
Image.network("https://cdn2.jianshu.io/assets/web/banner-s-club-aa8bdf19f8cf729a759da42e4a96f366.png"),//第三行是加载了一张网络图片
],
),
),
);
}
}
样式
ListTile和iOS中tableviewcell.style = defaultstyle很像,第三个cell是加载了一张网络图片
横向滑动的ListView
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "ListView",
home: Scaffold(
appBar: AppBar(title: Text("ListView"),),
body: MyList() //把ListView提出去了,调用自定义的类
),
);
}
}
//这里是把ListView提取封装出来了
class MyList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView(
scrollDirection: Axis.horizontal, //设置ListView滑动方向是横向,对应的还有竖直的
itemExtent: 120, //item的宽度
children: <Widget>[
Container(color: Colors.black,),
Container(color: Colors.pink,),
Container(color: Colors.black,),
Container(color: Colors.pink,),
Container(color: Colors.black,),
Container(color: Colors.pink,),
Container(color: Colors.black,),
Container(color: Colors.pink,),
],
);
}
}
上面介绍的都属于静态列表,适用于已确定item个数切个数不多的情况下使用,如果是动态的话,需要使用动态列表
动态列表组件
基本ListView.builder()
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Test",
home: Scaffold(
appBar: AppBar(
title: Text("Test"),
),
body: ListView.builder(
itemCount: 100, //item的个数,相当于OC中的cell的个数
itemExtent: 50, //item的高度,这个是选填项,为null时,ListView 会动态地根据子 Widget 创建完成的结果,决定自身视图的高度
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text("标题$index"),subtitle: Text("副标题$index"),); //带有标题和副标题的样式
},
),
),
);
}
}
设置有分割线的ListView.separated
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Test",
home: Scaffold(
appBar: AppBar(
title: Text("Test"),
),
body: ListView.separated(
itemCount: 100,
separatorBuilder: (BuildContext context, int index) => index %2 ==0? Divider(color: Colors.green) : Divider(color: Colors.red),//index 为偶数,创建绿色分割线;index 为奇数,则创建红色分割线
itemBuilder: (BuildContext context, int index) => ListTile(title: Text("title $index"), subtitle: Text("body $index"))// 创建子 Widget
),
),
);
}
}
还有一种方法,是使用ListView.builder
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Test",
home: Scaffold(
appBar: AppBar(
title: Text("Test"),
),
body: ListView.builder(
itemCount: 100, //item的个数,相当于OC中的cell的个数
itemExtent: 50, //item的高度,这个是选填项,为null时,ListView 会动态地根据子 Widget 创建完成的结果,决定自身视图的高度
itemBuilder: (BuildContext context, int index) {
// 当是奇数列时 在每一列之前,添加一个1像素高的分隔线widget
if (index.isOdd) return new Divider();
return ListTile(title: Text("标题$index"),subtitle: Text("副标题$index"),); //带有标题和副标题的样式
},
),
),
);
}
}
CustomScrollView
用来解决多个ListView嵌套问题,处理多个需要自定义滚动效果的 Widget。在 CustomScrollView 中这些彼此独立的、可滚动的 Widget 被统称为 Sliver。
比如,ListView 的 Sliver 实现为 SliveList,AppBar的Sliver实现为SliverAppBar,这些Sliver不再维护各自的滚动状态,而是交由CustomScrollView统一管理,最终实现滑动效果的一致性。
视差滚动是指让多层背景以不同的速度移动,在形成立体滚动效果的同时,还能保证良好的视觉体验。
import "package:flutter/material.dart";
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "TextSpan",
home: Scaffold(
appBar: AppBar(title: Text("TextSpan富文本"),),
body: CustomScrollView(
slivers: <Widget>[ //作为头图控件,类似于tableview中的tableheaderview
SliverAppBar(
title: Text("标题"), //标题
floating: true, //设置悬浮样式
flexibleSpace: Image.network("http://cdn.duitang.com/uploads/item/201407/24/20140724190906_MCkXs.thumb.700_0.jpeg",fit: BoxFit.cover,),//设置悬浮头图背景
expandedHeight: 300, //头图的高度
),
SliverList( //作为列表控件
delegate: SliverChildBuilderDelegate(
(context,index)=>ListTile(title: Text("cell--$index")), //列表项创建方法
childCount: 20, //列表元素的个数
),
)
],
),
),
);
}
}
上拉加载更多
GridView组件(相当于iOS中的CollectionView)
GridView.count
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "GridView",
home: Scaffold(
appBar: AppBar(
title: Text("GridView"),
),
body: GridView.count(
padding: EdgeInsets.all(10), //内边距
crossAxisCount: 3, //每行显示的网格的数量
mainAxisSpacing: 3, //网格间的上下间距,相当于每行网格之间的间距
crossAxisSpacing: 2,//网格间的左右间距,相当于每列网格之间的间距。
childAspectRatio: 3/4, //每个网格的宽高比,可以用小数表示
children: <Widget>[
new Image.network('http://img5.mtime.cn/mt/2018/10/22/104316.77318635_180X260X4.jpg',fit: BoxFit.cover),
new Image.network('http://img5.mtime.cn/mt/2018/10/10/112514.30587089_180X260X4.jpg',fit: BoxFit.cover),
new Image.network('http://img5.mtime.cn/mt/2018/11/13/093605.61422332_180X260X4.jpg',fit: BoxFit.cover),
new Image.network('http://img5.mtime.cn/mt/2018/11/07/092515.55805319_180X260X4.jpg',fit: BoxFit.cover),
new Image.network('http://img5.mtime.cn/mt/2018/11/21/090246.16772408_135X190X4.jpg',fit: BoxFit.cover),
new Image.network('http://img5.mtime.cn/mt/2018/11/17/162028.94879602_135X190X4.jpg',fit: BoxFit.cover),
new Image.network('http://img5.mtime.cn/mt/2018/11/19/165350.52237320_135X190X4.jpg',fit: BoxFit.cover),
new Image.network('http://img5.mtime.cn/mt/2018/11/16/115256.24365160_180X260X4.jpg',fit: BoxFit.cover),
new Image.network('http://img5.mtime.cn/mt/2018/11/20/141608.71613590_135X190X4.jpg',fit: BoxFit.cover),
],
),
),
);
}
}
还有GridView(),用法和上面差不多,但是推荐使用的是GridView.count