widget使用合集
1.Stack 層疊組件 Stack 與 Align Stack 與 Positioned 實(shí)現(xiàn)定位布局
2.AspectRatio 根據(jù)設(shè)置調(diào)整子元素 child 的寬高比
3.Card 卡片組件
4.Wrap 實(shí)現(xiàn)瀑布流(橫向 或者 縱向)
5.自定義有狀態(tài)組件 StatefulWidget
6.BottomNavigationBar 實(shí)現(xiàn)底部導(dǎo)航欄多頁面
7.自定義頂部導(dǎo)航按鈕 圖標(biāo)、顏色 以及 TabBar 定義頂部 Tab 切換
8.FlutterDrawer 側(cè)邊欄 抽屜樣式
9.Flutter 按鈕組件合集
10.表單組件 TextField,Radio,CheckBox
Stack 層疊組件 Stack 與 Align Stack 與 Positioned 實(shí)現(xiàn)定位布局
stack 有點(diǎn)類似Android的FrameLayout,幀布局,配合Align或者Positioned來定位容器內(nèi)的組件位置
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
width: 300,
height: 300,
color: Colors.redAccent,
child: Stack(
alignment: Alignment.center,
children: <Widget>[
Align(
alignment: Alignment(-1, -1), //左上
child: Icon(
Icons.camera,
size: 32,
color: Colors.yellowAccent,
),
),
Align(
alignment: Alignment(0, 0), //中間
child: Icon(
Icons.supervised_user_circle,
size: 32,
color: Colors.blue,
),
),
Align(
alignment: Alignment(1, 1), //右下
child: Icon(
Icons.search,
size: 32,
color: Colors.white,
),
),
],
),
);
}
}
//配合positioned使用
children: <Widget>[
Positioned(
left: 10,
top: 10,
child: Icon(
Icons.camera,
size: 32,
color: Colors.yellowAccent,
),
),
Positioned(
right: 10,
top: 10,
child: Icon(
Icons.supervised_user_circle,
size: 32,
color: Colors.blue,
),
),
Positioned(
bottom: 0,
right: 0,
child: Icon(
Icons.search,
size: 32,
color: Colors.white,
),
),
],

positioned配合使用效果

層疊布局 小案例
class HomeContent extends StatelessWidget {
Widget _getData(BuildContext context, int index) {
return Container(
margin: EdgeInsets.only(top: 10),
height: 200,
child: Stack(
alignment: Alignment.bottomCenter,
fit: StackFit.passthrough,
children: <Widget>[
Align(
child: Image.network(
listData[index]["imageUrl"],
width: double.infinity,
fit: BoxFit.fitWidth,
),
),
Positioned(
bottom: 10,
child: Text(listData[index]["title"]),
)
],
),
);
}
@override
Widget build(BuildContext context) {
return Container(
child: ListView.builder(
itemBuilder: _getData,
itemCount: listData.length,
),
);
}
}

AspectRatio 根據(jù)設(shè)置調(diào)整子元素 child 的寬高比
AspectRation 的子元素 寬度 占據(jù) 父組件,高度根據(jù)寬高比而定,aspectRatio設(shè)置寬高比 比如16/9
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.all(10),
color: Colors.pinkAccent,
child: AspectRatio(
aspectRatio: 3 / 1,
child: Container(
color: Colors.blue,
),
),
);
}
Card 組件
Card 是卡片組件塊,內(nèi)容可以由大多數(shù)類型的 Widget 構(gòu)成,Card 具有圓角和陰影,這讓它 看起來有立體感。
class HomeContent extends StatelessWidget {
Widget _getData(BuildContext context, int index) {
return Card(
margin: EdgeInsets.all(10),
child: Column(
children: <Widget>[
// 16/9的圖片
AspectRatio(
aspectRatio: 20 / 9,
child: Image.network(
listData[index]["imageUrl"],
fit: BoxFit.cover,
),
),
ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(listData[index]["imageUrl"]),
),
title: Text(listData[index]["title"]),
subtitle: Text(
listData[index]["author"],
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
)
],
),
);
}
@override
Widget build(BuildContext context) {
return Container(
child: ListView.builder(
itemBuilder: _getData,
itemCount: listData.length,
),
);
}
}


Wrap 實(shí)現(xiàn)瀑布流(橫向 或者 縱向)
單行的 Wrap 跟 Row 表現(xiàn)幾乎一致,單列的 Wrap 跟 Row實(shí)現(xiàn)效果也差不多。但是多行或者多列的時(shí)候,Wrap會(huì)根據(jù) 父控件的寬高,自動(dòng)換行或者換列。。
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Wrap(
spacing: 10, //主軸間距
runSpacing: 10, //次軸間距
alignment: WrapAlignment.spaceAround, //對(duì)齊方式
children: <Widget>[
MyButton("shadow1"),
MyButton("shadow2"),
MyButton("shadow3"),
MyButton("shadow4"),
MyButton("shadow5"),
MyButton("shadow6"),
MyButton("shadow7"),
MyButton("shadow8"),
MyButton("shadow9"),
MyButton("shadow10"),
MyButton("shadow11"),
],
);
}
}
class MyButton extends StatelessWidget {
String text;
MyButton(this.text);
@override
Widget build(BuildContext context) {
return RaisedButton(
child: Text(this.text),
textColor: Colors.pinkAccent,
onPressed: () {
print("hello shadow?。?!");
});
}
}

有狀態(tài)組件
在 Flutter 中自定義組件其實(shí)就是一個(gè)類,這個(gè)類需要繼承 StatelessWidget/StatefulWidget。
StatelessWidget 是無狀態(tài)組件,狀態(tài)不可變的 widget StatefulWidget 是有狀態(tài)組件,持有的狀態(tài)可能在 widget 生命周期改變。通俗的講:如果我 們想改變頁面中的數(shù)據(jù)的話這個(gè)時(shí)候就需要用到 StatefulWidget
class HomeWidget extends StatefulWidget {
@override
MyState2 createState() => MyState2();
}
///自定義有狀態(tài)組件之動(dòng)態(tài)計(jì)數(shù)器
class MyState extends State<HomeWidget> {
int countNum = 1;
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
SizedBox(
height: 100,
),
Chip(
label: Text(this.countNum.toString()),
),
RaisedButton(
child: Text("添加"),
onPressed: () {
setState(() {
this.countNum++;
print(this.countNum);
});
},
)
],
);
}
}
///自定義有狀態(tài)組件之動(dòng)態(tài)添加列表數(shù)據(jù)
class MyState2 extends State<HomeWidget> {
List mList = new List();
@override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
Column(
children: mList.map((value) {
return ListTile(
title: Text(value),
);
}).toList(),
),
RaisedButton(
child: Text("動(dòng)態(tài)添加列表數(shù)據(jù)"),
onPressed: () {
setState(() {
mList.add("hello shadow1");
mList.add("hello shadow2");
});
},
)
],
);
}
}

BottomNavigationBar 實(shí)現(xiàn)底部導(dǎo)航欄多頁面
BottomNavigationBar 是底部導(dǎo)航條,可以讓我們定義底部 Tab 切換,bottomNavigationBar 是 Scaffold 組件的參數(shù)
items List<BottomNavigationBarItem> 底部導(dǎo)航條按鈕集合
iconSize icon 圖標(biāo)大小
currentIndex 默認(rèn)選中第幾個(gè)
onTap 選中變化回調(diào)函數(shù)
fixedColor 選中的顏色
type 底部按鈕的排放方式 BottomNavigationBarType.fixed 平均分配 --- BottomNavigationBarType.shifting 默認(rèn)占據(jù)位置
下面實(shí)現(xiàn)了tab頁面切換的簡易小demo,為頁面代碼做了拆分
mainDart
import 'package:flutter/material.dart';
import 'pages/Tabs.dart';
main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.light(),
title: "MaterialApp title",
home: Tabs(),
);
}
}
Tabs.dart
import 'package:flutter/material.dart';
import 'package:flutter_demp/pages/tabs/CategoryPage.dart';
import 'package:flutter_demp/pages/tabs/HomePage.dart';
import 'package:flutter_demp/pages/tabs/MinePage.dart';
import 'package:flutter_demp/pages/tabs/ShopCartPage.dart';
class Tabs extends StatefulWidget {
@override
StateTabs createState() => StateTabs();
}
class StateTabs extends State<Tabs> {
//當(dāng)前選擇的tab
int _currentIndex = 0;
//page頁面集合
List pageList = [HomePage(), CategoryPage(), ShopCartPage(), MinePage()];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("APPBar title"),
),
body: pageList[_currentIndex], //根據(jù)底部tab切換,選擇不同的page界面
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), title: Text("首頁")),
BottomNavigationBarItem(icon: Icon(Icons.category), title: Text("分類")),
BottomNavigationBarItem(icon: Icon(Icons.shopping_cart), title: Text("購物車")),
BottomNavigationBarItem( icon: Icon(Icons.supervised_user_circle), title: Text("我的")),
],
onTap: (index) {
setState(() { //tab切換選擇事件監(jiān)聽,更新狀態(tài)
_currentIndex = index;
});
},
currentIndex: _currentIndex, //當(dāng)前選擇的tab
fixedColor: Colors.pinkAccent, //選中時(shí)的顏色
type: BottomNavigationBarType.fixed, //底部tab之間的排序方式
),
);
}
}
HomePage,其他的tab頁面與此類似
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text("我是首頁");
}
}

自定義頂部導(dǎo)航按鈕 圖標(biāo)、顏色 以及 TabBar 定義頂部 Tab 切換
Flutter AppBar 自定義頂部按鈕圖 標(biāo)、顏色
屬性 描述
leading 在標(biāo)題前面顯示的一個(gè)控件,在首頁通常顯示應(yīng)用 的 logo;在其他界面通常顯示為返回按鈕
title 標(biāo)題,通常顯示為當(dāng)前界面的標(biāo)題文字,可以放組 件
actions 通常使用 IconButton 來表示,可以放按鈕組
bottom 通常放 tabBar,標(biāo)題下面顯示一個(gè) Tab 導(dǎo)航欄
backgroundColor 導(dǎo)航背景顏色
iconTheme 圖標(biāo)樣式
textTheme 文字樣式
centerTitle 標(biāo)題是否居中顯示
class AppBarDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
//左側(cè)按鈕
leading: IconButton(
icon: Icon(
Icons.backspace,
),
onPressed: () {
print("left back onclick");
},
),
//右側(cè)按鈕
actions: <Widget>[
IconButton(
icon: Icon(
Icons.menu,
),
onPressed: () {
print("hello shadow menu");
},
),
IconButton(
icon: Icon(
Icons.search,
),
onPressed: () {
print("hello shadow search");
},
),
],
title: Text(
"商品詳情",
),
backgroundColor: Colors.pinkAccent,
centerTitle: true,
//頂部tab
bottom: TabBar(
tabs: <Widget>[
Text("商品"),
Text("詳情"),
],
indicatorColor: Colors.blue,
),
),
body: TabBarView(
children: <Widget>[
ListView(
children: <Widget>[
ListTile(
title: Text("第一頁"),
),
ListTile(
title: Text("第一頁"),
),
ListTile(
title: Text("第一頁"),
)
],
),
ListView(
children: <Widget>[
ListTile(
title: Text("第二頁"),
),
ListTile(
title: Text("第二頁"),
),
ListTile(
title: Text("第二頁"),
)
],
),
],
),
));
}
}

NavigationBar 頁面 實(shí)現(xiàn)tabBar
scaffold可以互相嵌套
DefaultTabController ,TabBar,TabBarView
AppBar 中自定義 TabBar 實(shí) 現(xiàn)頂部 Tab 切換
TabBar 常見屬性:
屬性 描述
tabs 顯示的標(biāo)簽內(nèi)容,一般使用 Tab 對(duì)象,也可以是其他 的 Widget
controller TabController 對(duì)象
isScrollable 是否可滾動(dòng)
indicatorColor 指示器顏色
indicatorWeight 指示器高度
indicatorPadding 底部指示器的
Padding indicator 指示器
decoration, 例如邊框等
indicatorSize 指示器大小計(jì)算方式,
TabBarIndicatorSize.label 跟文 字等寬,
TabBarIndicatorSize.tab 跟每個(gè) tab 等寬
labelColor 選中 label 顏色
labelStyle 選中 label 的 Style
labelPadding 每個(gè) label 的 padding 值
unselectedLabelColor 未選中 label 顏色
unselectedLabelStyle 未選中 label 的 Style
import 'package:flutter/material.dart';
class CategoryPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: Row(
children: <Widget>[
Expanded(
child: TabBar(
labelColor: Colors.red,
indicatorColor: Colors.red,
unselectedLabelColor: Colors.white,
indicatorSize: TabBarIndicatorSize.label,
tabs: <Widget>[
Tab(
text: "hhhh",
),
Tab(
text: "kkkk",
)
],
),
)
],
),
),
body: TabBarView(
children: <Widget>[Text("hhhhh"), Text("kkkkk")],
),
),
);
}
}

TabControl 實(shí)現(xiàn)頂部 tabBar
import 'dart:html';
import 'package:flutter/material.dart';
class TabControlPage extends StatefulWidget {
@override
_TabControlPageState createState() => _TabControlPageState();
TabControlPage();
}
/// 使用TabControl創(chuàng)建tab,需要三個(gè)步驟,
/// 1.創(chuàng)建有狀態(tài)組件,with SingleTickerProviderStateMixin
/// 2.初始化生命周期中,實(shí)現(xiàn)tabControl實(shí)例
/// 3.在 TabBar和TabBarView中賦值controller: _tabController屬性
class _TabControlPageState extends State<TabControlPage>
with SingleTickerProviderStateMixin {
TabController _tabController;
///生命周期函數(shù),組件加載的時(shí)候調(diào)用
@override
void initState() {
super.initState();
//實(shí)現(xiàn)tabControl實(shí)例
_tabController = TabController(length: 7, vsync: this);
//tab 切換監(jiān)聽
_tabController.addListener(() {
print(_tabController.index);
});
}
///生命周期函數(shù) 組件關(guān)閉的時(shí)候被調(diào)用
@override
void dispose() {
super.dispose();
_tabController.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("TabControl"),
bottom: TabBar(
isScrollable: true,
tabs: <Widget>[
Tab(
text: "推薦1",
),
Tab(
text: "推薦2",
),
Tab(
text: "推薦3",
),
Tab(
text: "推薦4",
),
Tab(
text: "推薦5",
),
Tab(
text: "推薦6",
),
Tab(
text: "推薦7",
),
],
controller: _tabController,
),
),
body: TabBarView(
controller: _tabController,
children: <Widget>[
Text("推薦1"),
Text("推薦2"),
Text("推薦3"),
Text("推薦4"),
Text("推薦5"),
Text("推薦6"),
Text("推薦7"),
],
),
);
}
}

FlutterDrawer 側(cè)邊欄 抽屜樣式
在 Scaffold 組件里面?zhèn)魅?drawer 參數(shù)可以定義左側(cè)邊欄,傳入 endDrawer 可以定義右側(cè)邊 欄。
側(cè)邊欄默認(rèn)是隱藏的,我們可以通過手指滑動(dòng)顯示側(cè)邊欄,也可以通過點(diǎn)擊按鈕顯示側(cè) 邊欄。
DrawerHeader 可以自定義布局
屬性 描述
decoration 設(shè)置頂部背景顏色
child 配置子元素
padding 內(nèi)邊距
margin 外邊距
UserAccountsDrawerHeader 固定格式
屬性 描述
decoration 設(shè)置頂部背景顏色
accountName 賬戶名稱
accountEmail 賬戶郵箱
currentAccountPicture 用戶頭像
otherAccountsPictures 用來設(shè)置當(dāng)前賬戶其他賬戶頭像
Widget build(BuildContext context) {
return Scaffold(
/*appBar: AppBar(
title: Text("APPBar title"),
),*/
body: pageList[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), title: Text("首頁")),
BottomNavigationBarItem(
icon: Icon(Icons.category), title: Text("分類")),
BottomNavigationBarItem(
icon: Icon(Icons.shopping_cart), title: Text("購物車")),
BottomNavigationBarItem(
icon: Icon(Icons.supervised_user_circle), title: Text("我的")),
],
onTap: (index) {
setState(() {
_currentIndex = index;
});
},
currentIndex: _currentIndex,
fixedColor: Colors.pinkAccent,
type: BottomNavigationBarType.fixed,
),
drawer: Drawer(
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Expanded(
/* child: DrawerHeader(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
"https://www.itying.com/images/flutter/1.png"),fit: BoxFit.cover)),
child: Column(
children: <Widget>[
CircleAvatar(
backgroundImage: NetworkImage(
"https://www.itying.com/images/flutter/3.png"),
),
Text("付小影子")
],
))*/
child: UserAccountsDrawerHeader(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
"https://www.itying.com/images/flutter/1.png"),
fit: BoxFit.cover)),
accountName: Text("付小影子"),
accountEmail: Text("111111@qq.com"),
currentAccountPicture: CircleAvatar(
backgroundImage: NetworkImage(
"https://www.itying.com/images/flutter/3.png"),
),
),
)
],
),
ListTile(
leading: Icon(Icons.home),
title: Text("首頁中心"),
onTap: () {
print("跳轉(zhuǎn) 首頁");
},
),
Divider(),
ListTile(
leading: Icon(Icons.people),
title: Text("用戶中心"),
onTap: () {
print("跳轉(zhuǎn) 用戶中心");
},
),
Divider(),
ListTile(
leading: Icon(Icons.settings),
title: Text("設(shè)置中心"),
onTap: () {
print("跳轉(zhuǎn) 設(shè)置中心");
},
),
Divider(),
],
),
),
);
}

Flutter 按鈕組件
Flutter 里有很多的 Button 組件很多,常見的按鈕組件有:RaisedButton、FlatButton、 IconButton、OutlineButton、ButtonBar、FloatingActionButton 等。
RaisedButton :凸起的按鈕,其實(shí)就是 Material Design 風(fēng)格的 Button
FlatButton :扁平化的按鈕
OutlineButton:線框按鈕
IconButton :圖標(biāo)按鈕
ButtonBar:按鈕組
FloatingActionButton:浮動(dòng)按鈕
按鈕共用 屬性名稱 值類型 屬性值
onPressed VoidCallback ,一般接收一個(gè) 方法 必填參數(shù),按下按鈕時(shí)觸發(fā)的回調(diào),接收一個(gè) 方法,傳 null 表示按鈕禁用,會(huì)顯示禁用相關(guān) 樣式
child Widget 文本控件
textColor Color 文本顏色
color Color 按鈕的顏色
disabledColor Color 按鈕禁用時(shí)的顏色
disabledTextColor Color 按鈕禁用時(shí)的文本顏色
splashColor Color 點(diǎn)擊按鈕時(shí)水波紋的顏色
highlightColor Color 點(diǎn)擊(長按)按鈕后按鈕的顏色
elevation double 陰影的范圍,值越大陰影范圍越大
padding 內(nèi)邊距
shape 設(shè)置按鈕的形狀 shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), )
shape: CircleBorder( side: BorderSide( color: Colors.white, ) )
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
child: Text("普通按鈕"),
onPressed: () {
print("普通按鈕");
}),
SizedBox(
width: 10,
),
RaisedButton(
textColor: Colors.white,
color: Colors.blue,
child: Text("顏色按鈕"),
onPressed: () {
print("顏色按鈕");
}),
SizedBox(
width: 10,
),
RaisedButton(
textColor: Colors.white,
color: Colors.blue,
child: Text("陰影按鈕"),
elevation: 10,
onPressed: () {
print("陰影按鈕");
}),
],
),
SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton.icon(
icon: Icon(Icons.search),
label: Text("圖標(biāo)按鈕"),
color: Colors.blue,
textColor: Colors.white,
onPressed: () {
print("圖標(biāo)按鈕");
}),
SizedBox(
width: 10,
),
Container(
width: 100,
height: 30,
child: RaisedButton(
onPressed: () {
print("寬高固定");
},
child: Text("寬高按鈕"),
textColor: Colors.white,
color: Colors.pinkAccent,
),
)
],
),
SizedBox(
height: 10,
),
Row(
children: <Widget>[
Expanded(
child: Container(
height: 50,
margin: EdgeInsets.all(20),
child: RaisedButton(
child: Text("登錄"),
color: Colors.blue,
textColor: Colors.white,
onPressed: () {
print("登錄");
}),
))
],
),
SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 100,
height: 30,
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10))),
onPressed: () {
print("圓角按鈕");
},
child: Text("圓角按鈕"),
textColor: Colors.white,
color: Colors.pinkAccent,
),
),
SizedBox(
width: 10,
),
RaisedButton(
shape: CircleBorder(
side: BorderSide(
style: BorderStyle.none, color: Colors.blue, width: 12)),
onPressed: () {
print("圓角按鈕");
},
child: Text("圓角按鈕"),
textColor: Colors.white,
color: Colors.pinkAccent,
),
],
),
SizedBox(
height: 10,
),
Row(
children: <Widget>[
Expanded(
child: Container(
height: 40,
margin: EdgeInsets.all(10),
child: FlatButton(
color: Colors.pink,
textColor: Colors.white,
onPressed: () {
print("扁平化的按鈕 ");
},
child: Text("扁平化的按鈕 "))),
)
],
),
SizedBox(
height: 10,
),
Row(
children: <Widget>[
Expanded(
child: Container(
height: 40,
margin: EdgeInsets.all(10),
child: OutlineButton(
color: Colors.pink,
textColor: Colors.red,
borderSide: BorderSide(color: Colors.blue),
onPressed: () {
print("線框按鈕 ");
},
child: Text("線框按鈕"))),
)
],
)
],
);
}
}

FloatingActionButton 實(shí)現(xiàn) 底部 凸起按鈕效果
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: Container(
width: 50,
height: 50,
margin: EdgeInsets.only(top: 10),
child: FloatingActionButton(
child: Icon(Icons.add),
backgroundColor:
_currentIndex == 1 ? Colors.pinkAccent : Colors.yellow,
onPressed: () {
setState(() {
_currentIndex = 1;
});
}),
),

輸入框組件 TextField
TextField 表單常見屬性:
maxLines :設(shè)置此參數(shù)可以把文本框改為多行文本框
onChanged: 文本框改變的時(shí)候觸發(fā)的事件
decoration
hintText: 類似 html 中的 placeholder
border :配置文本框邊框 OutlineInputBorder 配合使用
labelText :lable 的名稱
labelStyle :配置 lable 的樣式
obscureText: 把文本框框改為密碼框
controller: controller 結(jié)合 TextEditingController()可以配置表單默認(rèn)顯示的內(nèi)容
Checkbox 常見屬性:
value: true 或者 false
onChanged: 改變的時(shí)候觸發(fā)的事件
activeColor: 選中的顏色、背景顏色
checkColor: 選中的顏色、Checkbox 里面對(duì)號(hào)的顏色
CheckboxListTile 常見屬性:
value: true 或者 false
onChanged: 改變的時(shí)候觸發(fā)的事件
activeColor: 選中的顏色、背景顏色
title: 標(biāo)題
subtitle: 二級(jí)標(biāo)題
secondary: 配置圖標(biāo)或者圖片
selected: 選中的時(shí)候文字顏色是否跟著改變
class _State extends State<MyApp> {
//設(shè)置初始值
var _textControl = TextEditingController();
bool _isSelect = true;
@override
void initState() {
super.initState();
_textControl.text = "付小影子";
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "flutter demo",
theme: ThemeData.light(),
home: Scaffold(
appBar: AppBar(
title: Text("輸入框"),
),
body: Padding(
padding: EdgeInsets.all(10),
child: Column(
children: <Widget>[
TextField(
//密碼框
obscureText: true,
//單行 or 多行 設(shè)置
maxLines: 1,
//輸入框樣式
decoration: InputDecoration(
//提示文字
hintText: "請(qǐng)輸入用戶名稱",
labelText: "用戶名",
icon: Icon(Icons.people),
//帶邊框
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.redAccent),
),
),
//初始值設(shè)置
controller: _textControl,
//輸入監(jiān)聽
onChanged: (value) {
setState(() {
_textControl.text = value;
print(value);
});
},
),
SizedBox(
height: 10,
),
Container(
//寬度 match_patch
width: double.infinity,
child: RaisedButton(
child: Text("登錄"),
onPressed: () {
print("輸入框內(nèi)容${_textControl.text}");
}),
),
SizedBox(
height: 10,
),
Checkbox(
value: _isSelect,
onChanged: (b) {
setState(() {
_isSelect = b;
print(b ? "選中" : "未選中");
});
}),
SizedBox(
height: 10,
),
CheckboxListTile(
title: Text("checkbox title"),
subtitle: Text("checkbox subtitle"),
secondary: Icon(Icons.people),
value: _isSelect,
onChanged: (b) {
setState(() {
_isSelect = b;
print(b ? "選中" : "未選中");
});
})
],
),
),
),
);
}
}

Radio、RadioListTile 單選按鈕組件
當(dāng)value的值跟groupValue 的值一致時(shí),意味著選中該按鈕。。groupValue 值對(duì)應(yīng)變量為同一個(gè),視為同一組單選按鈕,互斥
Radio 常用屬性:
value :單選的值
onChanged: 改變時(shí)觸發(fā)
activeColor :選中的顏色、背景顏色
groupValue :選擇組的值
RadioListTile 常用屬性:
value: true 或者 false
onChanged: 改變的時(shí)候觸發(fā)的事件
activeColor: 選中的顏色、背景顏色
title: 標(biāo)題
subtitle: 二級(jí)標(biāo)題
secondary: 配置圖標(biāo)或者圖片
groupValue: 選擇組的值
class _MyAPPState extends State<MyAPP> {
//性別 1男 2女
int sex = 1;
var flag = true;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Flutter demo",
theme: ThemeData.light(),
home: Scaffold(
appBar: AppBar(
title: Text("Radio 單選框"),
),
body: Padding(
padding: EdgeInsets.all(20),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Text("男:"),
Radio<int>(
value: 1,
groupValue: sex,
onChanged: (value) {
setState(() {
sex = value;
});
}),
SizedBox(width: 10),
Text("女:"),
Radio<int>(
value: 2,
groupValue: sex,
onChanged: (value) {
setState(() {
sex = value;
});
})
],
),
SizedBox(
height: 10,
),
RadioListTile(
value: 1,
groupValue: sex,
title: Text("Title"),
subtitle: Text("subTitle"),
selected: sex == 1,
secondary: Icon(Icons.print),
onChanged: (value) {
setState(() {
sex = value;
});
}),
SizedBox(height: 10),
RadioListTile(
value: 2,
groupValue: sex,
selected: sex == 2,
title: Text("第二個(gè) title"),
subtitle: Text("第二個(gè) subTitle"),
secondary: Image.network(
"https://www.itying.com/images/flutter/3.png"),
onChanged: (value) {
setState(() {
sex = value;
});
}),
SizedBox(
height: 10,
),
Text(sex == 1 ? "選中男生" : "選中女生"),
Switch(
value: flag,
onChanged: (value) {
setState(() {
flag = value;
});
})
],
),
),
));
}
}

開關(guān) Switch
value: 單選的值
onChanged: 改變時(shí)觸發(fā)
activeColor: 選中的顏色、背景顏色
Switch(
value: flag,
onChanged: (value) {
setState(() {
flag = value;
});
})
表單 demo小綜合
import 'package:flutter/material.dart';
main() {
runApp(FormDemoPage());
}
class FormDemoPage extends StatefulWidget {
FormDemoPage({Key key}) : super(key: key);
_FormDemoPageState createState() => _FormDemoPageState();
}
class _FormDemoPageState extends State<FormDemoPage> {
String username;
int sex = 1;
String info = '';
List hobby = [
{"checked": true, "title": "吃飯"},
{"checked": false, "title": "睡覺"},
{"checked": true, "title": "寫代碼"}
];
List<Widget> _getHobby() {
List<Widget> tempList = [];
for (var i = 0; i < this.hobby.length; i++) {
tempList.add(Row(
children: <Widget>[
Text(this.hobby[i]["title"] + ":"),
Checkbox(
value: this.hobby[i]["checked"],
onChanged: (value) {
setState(() {
this.hobby[i]["checked"] = value;
});
})
],
));
}
return tempList;
}
void _sexChanged(value) {
setState(() {
this.sex = value;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "表單 demo",
home: Scaffold(
appBar: AppBar(
title: Text("學(xué)員信息登記系統(tǒng)"),
),
body: Padding(
padding: EdgeInsets.all(20),
child: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(hintText: "輸入用戶信息"),
onChanged: (value) {
setState(() {
this.username = value;
});
},
),
SizedBox(height: 10),
Row(
children: <Widget>[
Text("男"),
Radio(
value: 1,
onChanged: this._sexChanged,
groupValue: this.sex),
SizedBox(width: 20),
Text("女"),
Radio(
value: 2,
onChanged: this._sexChanged,
groupValue: this.sex)
],
),
//愛好
SizedBox(height: 40),
Column(
children: this._getHobby(),
),
TextField(
maxLines: 4,
decoration: InputDecoration(
hintText: "描述信息", border: OutlineInputBorder()),
onChanged: (value) {
setState(() {
this.info = value;
});
},
),
SizedBox(height: 40),
Container(
width: double.infinity,
height: 40,
child: RaisedButton(
child: Text("提交信息"),
onPressed: () {
print(this.sex);
print(this.username);
print(this.hobby);
},
color: Colors.blue,
textColor: Colors.white,
),
)
],
),
),
),
);
}
}
