1、按钮
1、属性
onPressed:必填参数,按下按钮时触发的回调,接收一个方法,传 null 表示按钮禁用,会显示禁用相关样式。
child:子组件。
style:ButtonStyle 类型的样式。
ButtonStyle 属性
ButtonStyle ButtonStyle({
MaterialStateProperty<TextStyle?>? textStyle, //文本样式
MaterialStateProperty<Color?>? backgroundColor, //背景色
MaterialStateProperty<Color?>? foregroundColor, //前景色(文本颜色)
MaterialStateProperty<Color?>? overlayColor, //高亮色,按钮按下之后的颜色
MaterialStateProperty<Color?>? shadowColor, //阴影色
MaterialStateProperty<Color?>? surfaceTintColor, //表面色调颜色
MaterialStateProperty<double?>? elevation, //阴影度
MaterialStateProperty<EdgeInsetsGeometry?>? padding, //内容边距
MaterialStateProperty<Size?>? minimumSize, //最小尺寸
MaterialStateProperty<Size?>? fixedSize, //按钮尺寸
MaterialStateProperty<Size?>? maximumSize, //最大尺寸
MaterialStateProperty<Color?>? iconColor, //图标颜色
MaterialStateProperty<double?>? iconSize, //图标大小
MaterialStateProperty<BorderSide?>? side, //设置边框
MaterialStateProperty<OutlinedBorder?>? shape, //设置按钮的形状
MaterialStateProperty<MouseCursor?>? mouseCursor, //桌面端鼠标样式
VisualDensity? visualDensity, //视觉密度
MaterialTapTargetSize? tapTargetSize, //响应触摸区域
Duration? animationDuration, //动画持续时间
bool? enableFeedback, //是否启用反馈,如长按震动
AlignmentGeometry? alignment, //子组件对齐样式
InteractiveInkFeatureFactory? splashFactory, //没有水波纹效果
})
2、按钮分类
ElevatedButton:即"凸起"按钮,它默认带有阴影和灰色背景。按下后,阴影会变大。
ElevatedButton ElevatedButton({
Key? key,
required void Function()? onPressed, //点击事件
void Function()? onLongPress, //长按事件
void Function(bool)? onHover, //鼠标悬停时回调
void Function(bool)? onFocusChange, //焦点
ButtonStyle? style,
FocusNode? focusNode, //用于焦点管理和监听
//如果当前未将其范围内的其他节点作为焦点,则将此小部件选择为初始焦点时为 True
bool autofocus = false,
Clip clipBehavior = Clip.none, //裁剪
MaterialStatesController? statesController,
required Widget? child,
})
示例
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
print("ElevatedButton -- Click");
},
onLongPress: () {
print("ElevatedButton -- LongClick");
},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.green),
foregroundColor: MaterialStateProperty.all(Colors.white),
shadowColor: const MaterialStatePropertyAll(Colors.greenAccent),
overlayColor: const MaterialStatePropertyAll(Colors.transparent),//按钮点击时的高亮色
),
child: const Text("ElevatedButton"),
);
}
}
TextButton:文本按钮,默认背景透明并不带阴影。按下后,会有背景色。
//TextButton
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return TextButton(
child: const Text("TextButton"),
onPressed: () {
print("TextButton -- Click");
},
onLongPress: () {
print("TextButton -- Long Click");
},
autofocus: true,
style: TextButton.styleFrom(
backgroundColor: Colors.grey,
foregroundColor: Colors.red,
shadowColor: Colors.green,
),
);
}
}
OutlinedButton:默认有一个边框,不带阴影且背景透明。按下后,边框颜色会变亮、同时出现背景和阴影。
//OutlinedButton
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return OutlinedButton(
onPressed: () {
print("OutlinedButton -- Click");
},
onLongPress: () {
print("OutlinedButton -- Long Click");
},
style: const ButtonStyle(
backgroundColor: MaterialStatePropertyAll(Colors.green),
foregroundColor: MaterialStatePropertyAll(Colors.black),
overlayColor: MaterialStatePropertyAll(Colors.transparent),
),
child: const Text("OutlinedButton"),
);
}
}
IconButton:是一个可点击的 Icon,不包括文字,默认没有背景,点击后会出现背景。
//IconButton
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return IconButton(
icon: const Icon(Icons.thumb_up),
onPressed: () {
print("IconButton -- Click");
},
iconSize: 40, //图标大小
padding: const EdgeInsets.all(30),
alignment: Alignment.topLeft,
//以下两行可以取消按钮的默认点击效果
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
);
}
}
浮动按钮:是一个圆形图标按钮,它触发应用程序中的主要操作。
FloatingActionButton:它创建一个简单的圆形浮动按钮,其中包含一个子部件。T 必须有一个子参数来显示 widget 。
//FloatingActionButton
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return FloatingActionButton(onPressed: () {
print("FloatingActionButton -- Click");
},
backgroundColor: Colors.green,
foregroundColor: Colors.white,
child: const Icon(Icons.add),
);
}
}
FloatingActionButton.extended:它创建了一个宽的浮动按钮,其中包含一个图标和一个标签。它使用标签和图标参数,而不是子参数。
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return FloatingActionButton.extended(
onPressed: () {
print("FloatingActionButton.extended -- Click");
},
icon: const Icon(Icons.add),
backgroundColor: Colors.green,
foregroundColor: Colors.black,
label: const Text("Add"));
}
}
自适应按钮
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: Container(
height: 60,
margin: const EdgeInsets.all(10),
child: ElevatedButton(
child: const Text('自适应按钮'),
onPressed: () {
print("自适应按钮");
},
),
),
)
],
);
}
}
修改按钮宽高
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return SizedBox(
width: double.infinity,
height: 50,
child: ElevatedButton(
onPressed: () {
print("自定义宽高");
},
style: ElevatedButton.styleFrom(
foregroundColor: Colors.red,
backgroundColor: Colors.green,
),
child: const Text("自定义宽高")),
);
}
}
2、Wrap
Wrap 可以实现流布局,单行的 Wrap 跟 Row 表现几乎一致,单列的 Wrap 则跟 Column 表现几乎一致。但 Row 与 Column 都是单行单列的,Wrap 则不是,mainAxis 上空间不足时,则向 crossAxis 上去扩展显示。
1、属性
Wrap Wrap({
Key? key,
Axis direction = Axis.horizontal, //主轴的方向,默认水平
WrapAlignment alignment = WrapAlignment.start, //主轴的对其方式
double spacing = 0.0, //主轴方向上的间距
//run 的对齐方式。run 可以理解为新的行或者列,如果是水平方向布局的话,run 可以理解为新的一行。
WrapAlignment runAlignment = WrapAlignment.start,
double runSpacing = 0.0, //run的间距
WrapCrossAlignment crossAxisAlignment = WrapCrossAlignment.start, //次轴对齐方式
TextDirection? textDirection, //文本方向
VerticalDirection verticalDirection = VerticalDirection.down, // children 摆放顺序,默认是down。
Clip clipBehavior = Clip.none,
List<Widget> children = const <Widget>[],
})
2、使用
class HomePage extends StatelessWidget {
const HomePage({super.key});
List<Widget> _customButton() {
List<Widget> list = [];
for (var e in listData) {
list.add(XSHButton(e["title"], onPressed: () {
print("标题: " + e["title"]);
}));
}
return list;
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(3),
child: Wrap(
spacing: 5,
runSpacing: 5,
// direction: Axis.vertical,
// alignment: WrapAlignment.start,
// runAlignment: WrapAlignment.center,
children: _customButton(),
),
);
}
}
//自定义按钮
// ignore: must_be_immutable
class XSHButton extends StatelessWidget {
String text;
void Function() onPressed;
XSHButton(this.text, {super.key, required this.onPressed});
@override
Widget build(BuildContext context) {
return ElevatedButton(
style: const ButtonStyle(
backgroundColor:
MaterialStatePropertyAll(Color.fromARGB(255, 236, 233, 233)),
foregroundColor: MaterialStatePropertyAll(Colors.black45),
),
onPressed: onPressed,
child: Text(text),
);
}
}
3、在 Flutter 中自定义组件其实就是一个类,这个类需要继承 StatelessWidget 或者 StatefulWidget。
StatelessWidget是无状态组件,状态不可变的 widget。
StatefulWidget是有状态组件,持有的状态可能在 widget 生命周期改变。如果想改变页面中数据的话这个时候就需要用到 StatefulWidget。
使用示例
//计数器
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int countNum = 0;
@override
Widget build(BuildContext context) {
return Center(
child: Column(
children: [
const SizedBox(
height: 100,
),
Text(
"数字是: $countNum",
style: const TextStyle(color: Colors.red, fontSize: 20),
),
const SizedBox(
height: 100,
),
ElevatedButton(
onPressed: () {
setState(() {
countNum++;
});
},
child: const Text("增加")),
],
),
);
}
}
//动态列表
class HomePage1 extends StatefulWidget {
const HomePage1({super.key});
@override
State<HomePage1> createState() => _HomePage1State();
}
class _HomePage1State extends State<HomePage1> {
List<String> list = [];
@override
Widget build(BuildContext context) {
return ListView(
children: [
Column(
children: list.map((e) {
return ListTile(
title: Text(e),
);
}).toList(),
),
const SizedBox(
height: 10,
),
Padding(
padding: const EdgeInsets.all(10),
child: ElevatedButton(
onPressed: () {
setState(() {
list.add("第 ${list.length + 1} 条数据");
});
},
child: const Text("增加一条数据")),
),
],
);
}
}
刷新页面:setState 方法。
网友评论