Flutter 的核心设计思想便是:Everythind is a Widget。在flutter的世界里,包括views,view controllers,layouts等在内的概念都建立在Widget之上。widget是flutter功能的抽象描述。所以掌握Flutter的基础就是学会使用widget开始。
Text:创建一个Text文本
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text("title"),
),
body: MyHomePage(),
),
);
}
}
class MyHomePage extends StatelessWidget {
final String title;
MyHomePage({Key key, this.title}) : super(key: key);
@override
Widget build(BuildContext context) {
return Text(
"Android进阶之旅",
style: TextStyle(
fontSize: 20,
color: Colors.teal
),
);
}
}
属性:
maxLines: 最大行数
overflow:超出显示方式
textAlign:文本对齐方式
style:文本样式,包括fontSize、color等
效果:
创建一个按钮
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
FloatingActionButton(
child: Text("+", style: TextStyle(fontSize: 30)),
onPressed: () {
print("FloatingActionButton Click");
},
),
RaisedButton(
child: Text("RaisedButton"),
onPressed: () {
print("RaisedButton Click");
},
),
FlatButton(
child: Text("FlatButton"),
onPressed: () {
print("FlatButton Click");
},
),
OutlineButton(
child: Text("OutlineButton"),
onPressed: () {
print("OutlineButton Click");
},
),
RaisedButton(
child: Text("登录",
style: TextStyle(color:Colors.white),
),
color: Colors.red,
highlightColor: Colors.red[600], //添加按下背景
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)), //设置圆角
onPressed: () {
print("登录");
},
)
],
);
}
}
效果:
-
图片Widget
Image组件属性:
const Image({
...
this.width, //图片的宽
this.height, //图片高度
this.color, //图片的混合色值
this.colorBlendMode, //混合模式
this.fit,//缩放模式
this.alignment = Alignment.center, //对齐方式
this.repeat = ImageRepeat.noRepeat, //重复方式
...
})
加载项目资源图片:
首先,需要在项目中与lib创建平级的文件夹,比如images,然后将图片资源拷如images中。然后需要在pubspec.yaml文件中声明资源,比如:
assets:
- images/test.jpeg
加载本地图片代码:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text("title"),
),
body: Container(
child: Image.asset(
"images/test.jpeg",
width: 100,
height: 100,
alignment: Alignment.topCenter,
),
width: 300,
height: 300,
),
),
);
}
}
效果:
加载网络资源图片:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text("title"),
),
body: Container(
child: Image.network(
"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1602884612610&di=99e5e92e7d3fd95d9c922f29c35f4b61&imgtype=0&src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2Fb%2F57a2a20321de9.jpg",
alignment: Alignment.topCenter,
),
width: 300,
height: 300,
),
),
);
}
}
圆角图片:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text("title"),
),
body: Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Image.network(
"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1602884612610&di=99e5e92e7d3fd95d9c922f29c35f4b61&imgtype=0&src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2Fb%2F57a2a20321de9.jpg",
alignment: Alignment.topCenter,
)
),
),
),
);
}
}
效果:
TextFiled
TextField用于接收用户的文本输入。常用属性:
keyboardType键盘的类型,style设置样式,textAlign文本对齐方式,maxLength最大显示行数等等;
decoration:用于设置输入框相关的样式
icon:设置左边显示的图标
labelText:在输入框上面显示一个提示的文本
hintText:显示提示的占位文字
border:输入框的边框,默认底部有一个边框,可以通过InputBorder.none删除掉
filled:是否填充输入框,默认为false
fillColor:输入框填充的颜色
controller:
onChanged:监听输入框内容的改变,传入一个回调函数
onSubmitted:点击键盘中右下角的down时,会回调的一个函数
代码:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text("title"),
),
body: Center(
child: TextField(
decoration: InputDecoration(
labelText: "userName",
hintText: "请输入用户名",
filled: true,
fillColor: Colors.lightGreenAccent
),
maxLines: 1,
onChanged: (value) {
},
onSubmitted: (value) {
},
),
),
),
);
}
}
效果:
-
Form
Form表单也是一个Widget,可以在里面放入我们的输入框。但是Form表单中输入框必须是FormField类型的。这里我们实现登录框的控件。
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: Form(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextFormField(
decoration: InputDecoration(
icon: Icon(Icons.people),
labelText: "userName"
),),
TextFormField(
decoration: InputDecoration(
icon: Icon(Icons.lock),
labelText: "passWord",
),
),
Container(
width: double.infinity,
height: 45,
child: RaisedButton(
child: Text("login",
style: TextStyle(color:Colors.white, fontSize: 17)
),
highlightColor: Colors.lightGreen,
color: Colors.red,
),
margin: EdgeInsets.all(10),
)
],
),
),
)
);
}
}
效果:
ListView
ListView属性代码,与Android中ListView功能一样的列表控件。
ListView({
Key key,
Axis scrollDirection: Axis.vertical,//滚动方向
bool reverse: false,//十分反向显示数据
ScrollController controller,
bool primary,
ScrollPhysics physics,//物理滚动
bool shrinkWrap: false,
EdgeInsetsGeometry padding,
this.itemExtent,//item有效范围
bool addAutomaticKeepAlives: true,//自动保存视图缓存
bool addRepaintBoundaries: true,//添加重绘边界
List<Widget> children: const <Widget>[],
})
示例中,在ListView的children数组子组件中,添加了多个ListTile,代码如下:
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new ListView(
children: <Widget>[
new ListTile(
leading: new Icon(Icons.access_alarm_rounded),
title: Text("闹钟"),
),
new ListTile(
leading: new Icon(Icons.account_balance_rounded),
title: Text("主页"),
),
new ListTile(
leading: new Icon(Icons.add_a_photo_outlined),
title: Text("相机"),
),
new ListTile(
leading: new Icon(Icons.airplanemode_on_rounded),
title: Text("飞机"),
),
new ListTile(
leading: new Icon(Icons.account_circle),
title: Text("头像"),
)
],
);
}
}
效果:
上面ListView是静态添加的少量数据,所以不能滑动,在实际情况数据多,需要滑动页面的多数据ListView,那么久需要使用ListView.builder。
相比于new ListView()只不过多出了两个参数而已,一个是itemCount指定item的数量,一个是itemBuilder,用来构建Item。
class HomeContent extends StatelessWidget {
List<String> list = new List();
HomeContent() {
for(var i=0;i<20;i++) {
list.add("第$i条数据");
}
}
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: list.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(list[index]),
);
},
);
}
}
效果:
-
GridView
GirView的用法和ListView类似,只不过由于GridView可以在一列或者一行显示多个Item,这个做Android的都知道。
新增属性:
SliverGridDelegateWithFixedCrossAxisCount:用于固定列数的场景;
SliverGridDelegateWithMaxCrossAxisExtent:用于子元素有最大宽度限制的场景;
子属性:
crossAxisCount :横轴元素个数
crossAxisSpacing:横轴间距
mainAxisSpacing:纵轴间距
childAspectRatio:子组件宽高比例
代码:
class HomeContent extends StatelessWidget {
List<ListItem> list = new List();
HomeContent() {
for (int i = 0; i < 20; i++) {
list.add(new ListItem(
"content",
Image.network(
"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1602884612610&di=99e5e92e7d3fd95d9c922f29c35f4b61&imgtype=0&src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2Fb%2F57a2a20321de9.jpg",
alignment: Alignment.topCenter)));
}
}
@override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: 10,
crossAxisSpacing: 0,
childAspectRatio: 2),
itemCount: list.length,
itemBuilder: (context, index) {
return ListTile(
leading: list[index].image,
title: Text(list[index].title),
);
});
}
}
class ListItem {
final String title;
final Image image;
ListItem(this.title, this.image);
}
效果:
参考
Flutter快速上车之Widget
Flutter(七)之Flutter的基础Widget
ListView&GirdView
网友评论