widget使用合集
1.Stack 层叠组件 Stack 与 Align Stack 与 Positioned 实现定位布局
2.AspectRatio 根据设置调整子元素 child 的宽高比
3.Card 卡片组件
4.Wrap 实现瀑布流(横向 或者 纵向)
5.自定义有状态组件 StatefulWidget
6.BottomNavigationBar 实现底部导航栏多页面
7.自定义顶部导航按钮 图标、颜色 以及 TabBar 定义顶部 Tab 切换
8.FlutterDrawer 侧边栏 抽屉样式
9.Flutter 按钮组件合集
10.表单组件 TextField,Radio,CheckBox
Stack 层叠组件 Stack 与 Align Stack 与 Positioned 实现定位布局
stack 有点类似Android的FrameLayout,帧布局,配合Align或者Positioned来定位容器内的组件位置
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,
),
),
],
33.png
positioned配合使用效果
44.png
层叠布局 小案例
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,
),
);
}
}
55.png
AspectRatio 根据设置调整子元素 child 的宽高比
AspectRation 的子元素 宽度 占据 父组件,高度根据宽高比而定,aspectRatio设置宽高比 比如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 是卡片组件块,内容可以由大多数类型的 Widget 构成,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,
),
);
}
}
66.png
77.png
Wrap 实现瀑布流(横向 或者 纵向)
单行的 Wrap 跟 Row 表现几乎一致,单列的 Wrap 跟 Row实现效果也差不多。但是多行或者多列的时候,Wrap会根据 父控件的宽高,自动换行或者换列。。
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Wrap(
spacing: 10, //主轴间距
runSpacing: 10, //次轴间距
alignment: WrapAlignment.spaceAround, //对齐方式
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!!!");
});
}
}
88.png
有状态组件
在 Flutter 中自定义组件其实就是一个类,这个类需要继承 StatelessWidget/StatefulWidget。
StatelessWidget 是无状态组件,状态不可变的 widget StatefulWidget 是有状态组件,持有的状态可能在 widget 生命周期改变。通俗的讲:如果我 们想改变页面中的数据的话这个时候就需要用到 StatefulWidget
class HomeWidget extends StatefulWidget {
@override
MyState2 createState() => MyState2();
}
///自定义有状态组件之动态计数器
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);
});
},
)
],
);
}
}
///自定义有状态组件之动态添加列表数据
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("动态添加列表数据"),
onPressed: () {
setState(() {
mList.add("hello shadow1");
mList.add("hello shadow2");
});
},
)
],
);
}
}
99.png
BottomNavigationBar 实现底部导航栏多页面
BottomNavigationBar 是底部导航条,可以让我们定义底部 Tab 切换,bottomNavigationBar 是 Scaffold 组件的参数
items List<BottomNavigationBarItem> 底部导航条按钮集合
iconSize icon 图标大小
currentIndex 默认选中第几个
onTap 选中变化回调函数
fixedColor 选中的颜色
type 底部按钮的排放方式 BottomNavigationBarType.fixed 平均分配 --- BottomNavigationBarType.shifting 默认占据位置
下面实现了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> {
//当前选择的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], //根据底部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切换选择事件监听,更新状态
_currentIndex = index;
});
},
currentIndex: _currentIndex, //当前选择的tab
fixedColor: Colors.pinkAccent, //选中时的颜色
type: BottomNavigationBarType.fixed, //底部tab之间的排序方式
),
);
}
}
HomePage,其他的tab页面与此类似
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text("我是首页");
}
}
10.png
自定义顶部导航按钮 图标、颜色 以及 TabBar 定义顶部 Tab 切换
Flutter AppBar 自定义顶部按钮图 标、颜色
属性 描述
leading 在标题前面显示的一个控件,在首页通常显示应用 的 logo;在其他界面通常显示为返回按钮
title 标题,通常显示为当前界面的标题文字,可以放组 件
actions 通常使用 IconButton 来表示,可以放按钮组
bottom 通常放 tabBar,标题下面显示一个 Tab 导航栏
backgroundColor 导航背景颜色
iconTheme 图标样式
textTheme 文字样式
centerTitle 标题是否居中显示
class AppBarDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
//左侧按钮
leading: IconButton(
icon: Icon(
Icons.backspace,
),
onPressed: () {
print("left back onclick");
},
),
//右侧按钮
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("第二页"),
)
],
),
],
),
));
}
}
13.png
NavigationBar 页面 实现tabBar
scaffold可以互相嵌套
DefaultTabController ,TabBar,TabBarView
AppBar 中自定义 TabBar 实 现顶部 Tab 切换
TabBar 常见属性:
属性 描述
tabs 显示的标签内容,一般使用 Tab 对象,也可以是其他 的 Widget
controller TabController 对象
isScrollable 是否可滚动
indicatorColor 指示器颜色
indicatorWeight 指示器高度
indicatorPadding 底部指示器的
Padding indicator 指示器
decoration, 例如边框等
indicatorSize 指示器大小计算方式,
TabBarIndicatorSize.label 跟文 字等宽,
TabBarIndicatorSize.tab 跟每个 tab 等宽
labelColor 选中 label 颜色
labelStyle 选中 label 的 Style
labelPadding 每个 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")],
),
),
);
}
}
14.png
TabControl 实现顶部 tabBar
import 'dart:html';
import 'package:flutter/material.dart';
class TabControlPage extends StatefulWidget {
@override
_TabControlPageState createState() => _TabControlPageState();
TabControlPage();
}
/// 使用TabControl创建tab,需要三个步骤,
/// 1.创建有状态组件,with SingleTickerProviderStateMixin
/// 2.初始化生命周期中,实现tabControl实例
/// 3.在 TabBar和TabBarView中赋值controller: _tabController属性
class _TabControlPageState extends State<TabControlPage>
with SingleTickerProviderStateMixin {
TabController _tabController;
///生命周期函数,组件加载的时候调用
@override
void initState() {
super.initState();
//实现tabControl实例
_tabController = TabController(length: 7, vsync: this);
//tab 切换监听
_tabController.addListener(() {
print(_tabController.index);
});
}
///生命周期函数 组件关闭的时候被调用
@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"),
],
),
);
}
}
15.png
FlutterDrawer 侧边栏 抽屉样式
在 Scaffold 组件里面传入 drawer 参数可以定义左侧边栏,传入 endDrawer 可以定义右侧边 栏。
侧边栏默认是隐藏的,我们可以通过手指滑动显示侧边栏,也可以通过点击按钮显示侧 边栏。
DrawerHeader 可以自定义布局
属性 描述
decoration 设置顶部背景颜色
child 配置子元素
padding 内边距
margin 外边距
UserAccountsDrawerHeader 固定格式
属性 描述
decoration 设置顶部背景颜色
accountName 账户名称
accountEmail 账户邮箱
currentAccountPicture 用户头像
otherAccountsPictures 用来设置当前账户其他账户头像
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("跳转 首页");
},
),
Divider(),
ListTile(
leading: Icon(Icons.people),
title: Text("用户中心"),
onTap: () {
print("跳转 用户中心");
},
),
Divider(),
ListTile(
leading: Icon(Icons.settings),
title: Text("设置中心"),
onTap: () {
print("跳转 设置中心");
},
),
Divider(),
],
),
),
);
}
16.png
Flutter 按钮组件
Flutter 里有很多的 Button 组件很多,常见的按钮组件有:RaisedButton、FlatButton、 IconButton、OutlineButton、ButtonBar、FloatingActionButton 等。
RaisedButton :凸起的按钮,其实就是 Material Design 风格的 Button
FlatButton :扁平化的按钮
OutlineButton:线框按钮
IconButton :图标按钮
ButtonBar:按钮组
FloatingActionButton:浮动按钮
按钮共用 属性名称 值类型 属性值
onPressed VoidCallback ,一般接收一个 方法 必填参数,按下按钮时触发的回调,接收一个 方法,传 null 表示按钮禁用,会显示禁用相关 样式
child Widget 文本控件
textColor Color 文本颜色
color Color 按钮的颜色
disabledColor Color 按钮禁用时的颜色
disabledTextColor Color 按钮禁用时的文本颜色
splashColor Color 点击按钮时水波纹的颜色
highlightColor Color 点击(长按)按钮后按钮的颜色
elevation double 阴影的范围,值越大阴影范围越大
padding 内边距
shape 设置按钮的形状 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("图标按钮"),
color: Colors.blue,
textColor: Colors.white,
onPressed: () {
print("图标按钮");
}),
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("线框按钮"))),
)
],
)
],
);
}
}
17.png
FloatingActionButton 实现 底部 凸起按钮效果
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;
});
}),
),
18.png
输入框组件 TextField
TextField 表单常见属性:
maxLines :设置此参数可以把文本框改为多行文本框
onChanged: 文本框改变的时候触发的事件
decoration
hintText: 类似 html 中的 placeholder
border :配置文本框边框 OutlineInputBorder 配合使用
labelText :lable 的名称
labelStyle :配置 lable 的样式
obscureText: 把文本框框改为密码框
controller: controller 结合 TextEditingController()可以配置表单默认显示的内容
Checkbox 常见属性:
value: true 或者 false
onChanged: 改变的时候触发的事件
activeColor: 选中的颜色、背景颜色
checkColor: 选中的颜色、Checkbox 里面对号的颜色
CheckboxListTile 常见属性:
value: true 或者 false
onChanged: 改变的时候触发的事件
activeColor: 选中的颜色、背景颜色
title: 标题
subtitle: 二级标题
secondary: 配置图标或者图片
selected: 选中的时候文字颜色是否跟着改变
class _State extends State<MyApp> {
//设置初始值
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 多行 设置
maxLines: 1,
//输入框样式
decoration: InputDecoration(
//提示文字
hintText: "请输入用户名称",
labelText: "用户名",
icon: Icon(Icons.people),
//带边框
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.redAccent),
),
),
//初始值设置
controller: _textControl,
//输入监听
onChanged: (value) {
setState(() {
_textControl.text = value;
print(value);
});
},
),
SizedBox(
height: 10,
),
Container(
//宽度 match_patch
width: double.infinity,
child: RaisedButton(
child: Text("登录"),
onPressed: () {
print("输入框内容${_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 ? "选中" : "未选中");
});
})
],
),
),
),
);
}
}
19.png
Radio、RadioListTile 单选按钮组件
当value的值跟groupValue 的值一致时,意味着选中该按钮。。groupValue 值对应变量为同一个,视为同一组单选按钮,互斥
Radio 常用属性:
value :单选的值
onChanged: 改变时触发
activeColor :选中的颜色、背景颜色
groupValue :选择组的值
RadioListTile 常用属性:
value: true 或者 false
onChanged: 改变的时候触发的事件
activeColor: 选中的颜色、背景颜色
title: 标题
subtitle: 二级标题
secondary: 配置图标或者图片
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("第二个 title"),
subtitle: Text("第二个 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;
});
})
],
),
),
));
}
}
23.png
开关 Switch
value: 单选的值
onChanged: 改变时触发
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("学员信息登记系统"),
),
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,
),
)
],
),
),
),
);
}
}
21.png
网友评论