SafeArea
Wrap
RichText
ClipRRect
MediaQuery
FutureBuilder
Flexible
SizedBox
Aligin
Divider
如果上面的组件你能够熟练使用,那么就可以关闭此页面去开心的玩耍啦。如果你不清楚他们有什么用法,那么久往下看吧。每一个都有代码示例哦。
直通车 https://api.flutter.dev/flutter/widgets/SafeArea-class.html
可以有效的防止刘海屏幕内容被遮挡的问题。 下面给出实列说明
先给出一段简单的代码看看
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
// At the top level of our app, we'll, create a ScopedModel Widget. This
// will provide the CounterModel to all children in the app that request it
// using a ScopedModelDescendant.
return MaterialApp(
title: "demo",
home: Scaffold(
body:SafeAreaDemo() ,
),
);
}
}
class SafeAreaDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color:Colors.blue ,
child:Text("Hello Demo", style: TextStyle(fontSize: 24),) ,
);
}
}
这就是一个很普通的一个Container包裹了一个文本,(这是一个没有AppBar的demo),我们看看再普通屏幕上的显示效果和刘海屏的效果
普通手机
刘海屏手机
class SafeAreaDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SafeArea(
child: Container(
color:Colors.blue ,
child:Text("Hello Demo", style: TextStyle(fontSize: 30),) ,
),
);
}
}
还是2种样式的效果看下
普通手机
刘海屏手机
可以看到加上了SafeArea标签以后在刘海屏手机和普通沙鸥国际上上能够有效的把我们内容的安全区域留出来,保证我们的内容不会被遮挡。
SafeArea内部是通过MediaQuery和Padding帮助我们实现了这样一个效果,如果有需要自己定制特殊的需求也可以自己用这种方法来实现。
直通车:https://api.flutter.dev/flutter/widgets/Wrap-class.html
防止控件超出屏幕区域之外,自适应子控件的排列方式
还是老样子先看看代码
class WarpDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Row(
children: [
Text(" Hell1 " ,style: TextStyle(fontSize: 24),),
Text(" Hell2 ",style: TextStyle(fontSize: 24),),
Text(" Hell3",style: TextStyle(fontSize: 24),),
Text(" Hell4 ",style: TextStyle(fontSize: 24),),
Text(" Hell5 ",style: TextStyle(fontSize: 24),),
Text(" Hell6 ",style: TextStyle(fontSize: 24),),
Text(" Hell7 ",style: TextStyle(fontSize: 24),),
Text(" Hell8 ",style: TextStyle(fontSize: 24),),
Text(" Hell9 ",style: TextStyle(fontSize: 24),),
],
),
);
}
}
这里我们用Row在一行里面显示了九个Text看看效果
可以看到右边出现了一个黄黑色的条,并且还有一行文字,
而且控制台也给出了错误警告信息
════════ Exception caught by rendering library ═════════════════════════════════════════════════════
The following assertion was thrown during layout:
A RenderFlex overflowed by 186 pixels on the right.
说我们的内容溢出了屏幕186个像素,这种时候怎么办呢,也可以使用ListView或者其他flex调整系数的方式来使我们的内容显示完全。这里我们还是讲我们这里使用Wrap来包裹我们的内容,让他自适应的去展示内容。
纠正后的代码
class WarpDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Wrap(
children: [
Text(" Hell1 " ,style: TextStyle(fontSize: 24),),
Text(" Hell2 ",style: TextStyle(fontSize: 24),),
Text(" Hell3",style: TextStyle(fontSize: 24),),
Text(" Hell4 ",style: TextStyle(fontSize: 24),),
Text(" Hell5 ",style: TextStyle(fontSize: 24),),
Text(" Hell6 ",style: TextStyle(fontSize: 24),),
Text(" Hell7 ",style: TextStyle(fontSize: 24),),
Text(" Hell8 ",style: TextStyle(fontSize: 24),),
Text(" Hell9 ",style: TextStyle(fontSize: 24),),
],
),
);
}
}
把Row替换成了Wrap
现在再来看看效果
使用Wrap组件可以让我们的内容不再溢出屏幕,并且也可以通过Wrap设置内部控件放置的方向是垂直的还是水平的。
可以实现富文本效果
先看效果
可以看到上面的效果是左边Hello和右边的颜色字号都不相同的,并且后面还有一个icon图标,在Android中我们是怎么做的呢,要么就是三个不同的控件组成,要么是利用Span来组合,在这里Flutter用了一种更简便的方式来给我们提供这种样式的编写。
代码部分
class RichTextDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: RichText(
text: TextSpan(
text: "Hello",
style: TextStyle(color: Colors.red,fontSize: 18),
children: [
TextSpan(text: "RichText", style: TextStyle(color: Colors.blue,fontSize: 28,)),
WidgetSpan(child: Icon(Icons.arrow_forward,color: Colors.deepPurpleAccent,))
]),
),
);
}
}
上面的代码利用了RichText 里面包裹TextSpan来实现了上图中的效果,当然还可以在文字中插入图片,达到图文混排的效果。
利用RichText和TextSpan,WidgetSpan可以实现我们不同控件的组合使用来排版我们的UI效果。可以实现富文本的效果
直通车 https://api.flutter.dev/flutter/widgets/ClipRRect-class.html
能够为控件实现圆角效果
先看下原始的效果
这个时候想要为我们的图片实现圆角就可以用这个组件包裹一下就ok了。
看看代码实现
class ClipRRectDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Container(
margin: EdgeInsets.symmetric(horizontal: 20),
child: ClipRRect(
child: Image.network(
"https://www.gexing.me/uploads/allimg/170308/6-1F30Q44135404.jpg"),
borderRadius:BorderRadius.circular(24.0)
),
));
}
}
实现后的效果
可以看到最后成功的为我们的图片添加上了圆角,当然我们也可以自己把这个组件封装一下,以后使用圆角图片就直接引用这个控件就ok啦。
ClipRRect可以为我们实现圆角效果,还有其他Clipxxx的类(ClipOval,ClipRect...),圆形,矩形等裁剪的效果,等着大家去探索
直通车
MediaQuery可以为我们提供一些屏幕相关的信息,比如屏幕宽高等信息
例子 ,比如我们有这样一个效果
原始代码
class MediaQueryDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: _buildContent(context),
);
}
_buildContent(BuildContext context) {
return Column(
children: [
Flexible(
flex: 5,
child: Container(
color: Colors.deepPurple,
),
),
Flexible(
flex: 5,
child: Container(
color: Colors.deepOrange,
),
),
],
);
}
}
可以看到在这里 我们横屏的时候效果不是那么好,我们横屏的时候想要改成左右结构的,这个时候我们就可以利用MediaQuery来让我们的应用在横屏的时候改变解构为左右结构,下面看看改变之后的效果。
上图可以看到,横屏的时候是左右结构,切换到竖屏以后 就变成上下结构的了,下面看看实现代码
class MediaQueryDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: _buildContent(context),
);
}
_buildContent(BuildContext context) {
MediaQueryData mediaQueryData = MediaQuery.of(context);
if (mediaQueryData.size.width < mediaQueryData.size.height) {
return Column(
children: [
Flexible(
flex: 5,
child: Container(
color: Colors.deepPurple,
),
),
Flexible(
flex: 5,
child: Container(
color: Colors.deepOrange,
),
),
],
);
} else {
return Row(
children: [
Flexible(
flex: 5,
child: Container(
color: Colors.deepPurple,
),
),
Flexible(
flex: 5,
child: Container(
color: Colors.deepOrange,
),
),
],
);
}
}
}
从上面可以看到我们利用了MediaQuery获取了MediaQueryData,然后判断了屏幕的宽高验证是横屏还是竖屏模式,然后返回我们不同的布局样式
直通车 https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
FuturBuilder 执行IO操作,异步操作的时候非常有用,我们可以根据当前执行的状态来优化我们相应的UI界面显示,
json文件
{
"demo": "Hello FuturBuilderDemo"
}
看下如何使用的
class FuturBuilderDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: FutureBuilder(
builder: (context, snapshot) {
if (snapshot.hasData) {
return Center(
child: Text("result:" + snapshot.data),
);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
future: _getdata(context),
),
);
}
_getdata(BuildContext context) async {
String data = await DefaultAssetBundle.of(context).loadString("assets/demo.json");
return data;
}
}
这里写得比较简单,但是用法已经说明了,我们在使用一些io操作,或者网络请求操作的时候,可以利用FuturBuilder的不同状态渲染我们ui界面
直通车 https://api.flutter.dev/flutter/widgets/Flexible-class.html
按照百分比的方式排列显示控件
代码样例
class FlexibleDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
Flexible(
flex: 1,
child: Container(
color: Colors.deepOrange,
)),
Flexible(
flex: 3,
child: Container(
color: Colors.deepPurple,
)),
Flexible(
flex: 5,
child: Container(
color: Colors.deepOrangeAccent,
)),
],
);
}
}
效果
Flexible组件为Column和Row提供更好的灵活性,并且使用flex为组件分配可用大小,能够达到百分比的方式控制组件的摆放
直通车 https://api.flutter.dev/flutter/widgets/SizedBox-class.html
可以约束内部的子控件大小,并且也可以通过内部的属性去适应父控件的大小
代码
class SizeBoxDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: Center(
child: SizedBox(
width: 200,
height: 50,
child: RaisedButton(
onPressed: () {},
child: Text("Button",style: TextStyle(color: Colors.white),),color: Colors.deepOrange,
),
),
),
);
}
}
效果
这里可以通过width和height限定Button的大小,还可以通过一些属性来更改已适应父布局的大小。看看效果
修改SizedBox width参数为
width: double.infinity,
修改SizedBox组件为
SizedBox.expand
效果为
这个时候就会撑满整个屏幕
使用SizeBox不仅可以用于约束子控件的大小,还可以作用占位符的使用,相当于Padding,大家可以自己去尝试下哦,
直通车https://api.flutter.dev/flutter/widgets/Align-class.html
该组件可以定义Align包裹的组件在父布局中的哪个位置显示
代码
class AlignDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
color: Colors.deepPurple,
child: Align(
alignment: Alignment.centerRight,
child: Container(
width: 50,
height: 50,
color: Colors.blue,
),
),
);
}
}
效果
从上面的代码我门可以分析出,我们50*50的Container组件会显示在最外面的大的Container中间位置的最右边,当然还可以设置其他的位置,比如左上 左下等,默认位置是剧中显示的。
Align有点类似于Android中的相对布局,只是这里的相对只能是对于父控件来设置
分割线
直通车 https://api.flutter.dev/flutter/material/Divider-class.html
代码
class DividerDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(top: 200),
child: SizedBox(
height: 200,
child: Column(
children: [
Divider(height: 1, color: Colors.deepOrange),
SizedBox(
height: 10,
),
Divider(height: 2, color: Colors.blue),
SizedBox(
height: 10,
),
Divider(height: 1, color: Colors.black),
],
),
),
);
}
}
效果
可以看到上面又三个Divider 分别对应了屏幕中的三条横线分割线,并且有不同的颜色
上面基本上就是这10个小组件的常用方法和效果了,其中有部分中间还有一些属性没有展示完全他的效果,大家可以自行去尝试看看效果。
大家一定要记得https://api.flutter.dev/flutter/material/material-library.html 这个网址,里面基本行包含了所有的控件,大家不清楚
该用什么控件可以上去找找咯。