Flutter 组件之 Button、Image、TextFie
2023-10-09 本文已影响0人
Abner_XuanYuan
1、Button
MaterialButton
const MaterialButton({
Key key,
//Function类型必传参数,为当按钮点击时的回调方法,如果为null,按钮将处于禁用状态
@required this.onPressed,
//Function类型可选命名参数,为当长按按钮时的回调方法
this.onLongPress,
//Function类型可选命名参数,为当按钮突出(高亮)显示或停止突出显示时调用的回调方法,参数bool类型
this.onHighlightChanged,
//ButtonTextTheme类型可选命名参数,用来定义按钮的基本颜色,最小尺寸,内部填充和形状的默认值
this.textTheme,
//Color类型可选命名参数,为按钮文本的颜色
this.textColor,
//Color类型可选命名参数,为按钮禁用时的按钮文本的颜色
this.disabledTextColor,
//Color类型可选命名参数,按钮状态为可用时且未被点击时的填充色
this.color,
//Color类型可选命名参数,为按钮禁用时的按钮填充颜色
this.disabledColor,
//Color类型可选命名参数,当按钮具有输入焦点时的填充颜色
this.focusColor,
//Color类型可选命名参数,指针悬停在按钮上时的填充颜色
this.hoverColor,
//Color类型可选命名参数,用于设置按钮的高亮颜色
this.highlightColor,
//Color类型可选命名参数,按钮点击时水波纹效果的颜色
this.splashColor,
//Brightness类型可选命名参数,用于设置按钮的主题亮度
this.colorBrightness,
//double类型可选命名参数,相对于其父级放置此按钮的z坐标,可用于控制凸起按钮下方的
//阴影大小,默认值为2,不能为负数
this.elevation,
//double类型可选命名参数,当按钮启用并具有焦点时,按钮的elevation
this.focusElevation,
//double类型可选命名参数,当按钮启用且指针悬停在按钮上方时,按钮的按钮的elevation
this.hoverElevation,
//double类型可选命名参数,按钮为启用状态并被按下时其相对于父级的高程
this.highlightElevation,
//double类型可选命名参数,当按钮为不可用状态时其相对于父级的高程
this.disabledElevation,
//EdgeInsetsGeometry类型可选命名参数,设置按钮的内边距
this.padding,
//ShapeBorder类型可选命名参数,设置按钮形状
this.shape,
//Clip类型可选命名参数,用于设置内容将被如何裁剪
this.clipBehavior = Clip.none,
//FocusNode类型可选命名参数,按钮的焦点节点
this.focusNode,
//bool类型可选命名命名参数,用于设置是否按钮为当前焦点
this.autofocus = false,
//MaterialTapTargetSize类型可选命名参数,设置按钮的最小点击尺寸
this.materialTapTargetSize,
//Duration类型可选命名参数,用于定义按钮形状或高亮变化的动画的持续时间
this.animationDuration
//double类型可选命名参数,按钮的最小宽度
this.minWidth,
//double类型可选命名参数,按钮的高度
this.height,
//bool类型可选命名参数,当检测到手势时,是否提供听觉视觉的反馈
this.enableFeedback = true,
//Widget类型可选命名参数,是为按钮设置的显示标签,可以为任意Widget,通常使用Text
this.child,
})
ButtonStyleButton
abstract class ButtonStyleButton extends StatefulWidget {
/// Create a [ButtonStyleButton].
const ButtonStyleButton({
Key key,
// VoidCallback类型可选命名参数
// typedef VoidCallback = void Function();
@required this.onPressed,
// 同上
@required this.onLongPress,
// ButtonStyle 类型
@required this.style,
//FocusNode 类型
@required this.focusNode,
//bool
@required this.autofocus,
//Clip
@required this.clipBehavior,
//Widget
@required this.child,
})
示例
import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text("第二个 Flutter"),
foregroundColor: Colors.green,
),
backgroundColor: Colors.orange,
body: const MyApp(),
),
));
}
//按钮
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ListView(
children: [
Column(
children: [
//普通按钮
ElevatedButton(
onPressed: () {
// print("普通按钮");
log(11111);
},
child: const Text("普通按钮")),
const SizedBox(
height: 10,
),//设置间距组件
//带图标的普通按钮
ElevatedButton.icon(
onPressed: () {
log(1111122222);
},
icon: const Icon(Icons.send),
label: const Text("带图标的普通按钮")),
const SizedBox(
height: 5,
),
//普通按钮属性
ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.yellow), //背景色
foregroundColor:
MaterialStateProperty.all(Colors.red) //文字颜色
),
onPressed: () {
log(1111133333);
},
child: const Text("普通按钮属性")),
const SizedBox(
height: 5,
),
/*
* 修改按钮的宽高
* 方式一:
* 在按钮的外层增加一个 Container 组件,通过设置 Container 组件的宽高,来实现按钮的宽高.
* 方式二:
* 在按钮的最外层包裹一层 ButtonTheme 组件,该组件里包含宽高属性.
*/
Container(
width: 400,
height: 44,
child: ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.yellow), //背景色
foregroundColor:
MaterialStateProperty.all(Colors.red), //文字颜色
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20), //设置圆角
)),
),
onPressed: () {
log(1111144444);
},
child: const Text("修改按钮的宽高")),
),
const SizedBox(
height: 5,
),
//圆形按钮
Container(
width: 100,
height: 100,
child: ElevatedButton(
style: const ButtonStyle(
shape: MaterialStatePropertyAll(CircleBorder(
side: BorderSide(color: Colors.yellow)))),
onPressed: () {
log(1111155555);
},
child: const Text("圆形按钮")),
),
const SizedBox(
height: 5,
),
//文本按钮
TextButton(
onPressed: () {
log(22222);
},
child: const Text("文本按钮")),
const SizedBox(
height: 5,
),
//边框按钮
OutlinedButton(
style: const ButtonStyle(
//修改边框颜色
side: MaterialStatePropertyAll(
BorderSide(width: 1, color: Colors.red))),
onPressed: () {
log(33333);
},
child: const Text("边框按钮")),
const SizedBox(
height: 5,
),
//icon 按钮
IconButton(
onPressed: () {
log(44444);
},
icon: const Icon(Icons.thumb_down)),
const SizedBox(
height: 5,
),
],
)
],
);
}
}
选择按钮
//下拉选择按钮
class BoxButtonDemo extends StatefulWidget {
const BoxButtonDemo({super.key});
@override
State<BoxButtonDemo> createState() => _BoxButtonDemoState();
}
class _BoxButtonDemoState extends State<BoxButtonDemo> {
// ignore: prefer_typing_uninitialized_variables
var selecValue;
@override
Widget build(BuildContext context) {
return DropdownButton(
items: const [
DropdownMenuItem(
value: 0,
child: Text("男"),
),
DropdownMenuItem(
value: 1,
child: Text("女"),
),
DropdownMenuItem(
value: 2,
child: Text("未知"),
),
],
onChanged: (value) {
setState(() {
selecValue = value;
});
},
value: selecValue,
hint: const Text("请选择性别"),
);
}
}
自定义按钮
import 'package:flutter/material.dart';
main(List<String> args) {
runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('基本部件 - Button'),
),
body: const Center(
child: HomeButtonsContent(),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
),
));
}
class HomeButtonsContent extends StatelessWidget {
const HomeButtonsContent({super.key});
@override
Widget build(BuildContext context) {
return const Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [ElevatedButtonDemo()],
),
CustomeButton(),
CustomeButton2(),
],
);
}
}
class ElevatedButtonDemo extends StatelessWidget {
const ElevatedButtonDemo({super.key});
@override
Widget build(BuildContext context) {
return ElevatedButton(
child: const Text('ElevatedButton'),
onPressed: () {
// ignore: avoid_print
print('ElevatedButton');
},
);
}
}
//自定义按钮 -- 带图片文字
class CustomeButton extends StatelessWidget {
const CustomeButton({super.key});
@override
Widget build(BuildContext context) {
return MaterialButton(
onPressed: () {
// ignore: avoid_print
print('CustomeButton');
},
color: Colors.purple,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
child: const Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.favorite,
color: Colors.red,
),
Text('提交')
],
));
}
}
//自定义按钮 -- 更新默认设置大小及内边距
class CustomeButton2 extends StatelessWidget {
const CustomeButton2({super.key});
@override
Widget build(BuildContext context) {
return ButtonTheme(
minWidth: 40,
height: 20,
padding: const EdgeInsets.all(5),
buttonColor: Colors.green,
focusColor: Colors.red,
child: OutlinedButton(
// ignore: sort_child_properties_last
child: const Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.favorite,
color: Colors.red,
),
Text('提交')
],
),
style: const ButtonStyle(
backgroundColor: MaterialStatePropertyAll(Colors.green),
foregroundColor: MaterialStatePropertyAll(Colors.orange)),
onPressed: () {
// ignore: avoid_print
print('CustomeButton2');
},
),
);
}
}
2、Image
const Image({
Key key,
//ImageProvider类型必传参数,为要显示的图像
@required this.image,
//ImageFrameBuilder类型可选命名参数,是一个Function,返回一个代表该图像的Widget
this.frameBuilder,
//ImageLoadingBuilder类型可选命名参数,用于指定在图像加载过程中向用户展示的Widget
this.loadingBuilder,
//String类型可选命名参数,为图像的语义标签
this.semanticLabel,
//bool类型可选命名参数,是否从语义中排除此图像
this.excludeFromSemantics = false,
//double类型可选命名参数,图像要显示的宽度
this.width,
//double类型可选命名参数,图像要显示的高度
this.height,
//Color类型可选命名参数,如果不为null,则使用colorBlendMode将此颜色与每个图像像素混合
this.color,
//BlendMode类型可选命名参数,用于设置color与图像混合的模式
this.colorBlendMode,
//BoxFit类型可选命名参数,用于设置图像的填充模式
this.fit,
//AlignmentGeometry类型可选命名参数,设置图像的对齐模式,其为抽象类,使用其子类Alignment
this.alignment = Alignment.center,
//ImageRepeat类型可选命名参数,用于设置布局中图像的重复模式
this.repeat = ImageRepeat.noRepeat,
//Rect类型可选命名参数,用于设置当一个图片被拉伸时的范围
this.centerSlice,
//bool类型可选命名参数,用于设置是否以TextDirection相同的方向来绘制图像
this.matchTextDirection = false,
//bool类型可选命名参数,用于设置在图像提供者更改时,是否继续显示旧图像。
//true为显示旧图像,false为暂时不显示任何图像
this.gaplessPlayback = false,
//FilterQuality类型可选命名参数,用于设置图片的过滤质量
this.filterQuality = FilterQuality.low,
})
1、网络图片
import 'package:flutter/material.dart';
/*
测试图片地址:
https://www.itying.com/images/201906/goods_img/1120_P_1560842352183.png
https://www.itying.com/themes/itying/images/ionic4.png
*/
main(List<String> args) {
runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('基本部件 - Image'),
),
body: const Center(
child: MyApp(),
),
),
));
}
///网络图片
class MyApp extends StatelessWidget {
const MyApp({super.key});
final String img1 = 'https://www.itying.com/themes/itying/images/ionic4.png';
@override
Widget build(BuildContext context) {
return Image(
image: NetworkImage(img1),
width: 400,
height: 400,
// colorBlendMode: BlendMode.clear,
repeat: ImageRepeat.repeat,//平铺
// fit: BoxFit.fitWidth,
// alignment: Alignment.topCenter,
// x : -1 ~ 1
// y : -1 ~ 1 因为现在fit 为 fitWidth, width已经填充满, 所以更改x无效
alignment: const Alignment(1, 0),
);
}
}
///网络图片
class ImageLoading2 extends StatelessWidget {
final String img1 =
'https://www.itying.com/themes/itying/images/ionic4.png';
const ImageLoading2({super.key});
@override
Widget build(BuildContext context) {
return Image.network(img1);
}
}
2、加载本地图片
加载本地图片,需要将图片引入,并且进行配置。
1、创建图片资源文件。
2、在 pubspec.yaml 文件中进行图片配置。

示例
//加载本地图片
class ImageLocalLoading extends StatelessWidget {
const ImageLocalLoading({super.key});
@override
Widget build(BuildContext context) {
return const Image(image: AssetImage('assets/images/xxxxx.jpg'));
}
}
3、占位图
///占位图
class PlaceholderImage extends StatelessWidget {
const PlaceholderImage({super.key});
@override
Widget build(BuildContext context) {
const String img1 = 'https://www.itying.com/themes/itying/images/ionic4.png';
return const FadeInImage(
placeholder: AssetImage('assets/images/xxxxx.jpg'),
fadeOutDuration: Duration(milliseconds: 200),
fadeInDuration: Duration(milliseconds: 50),
image: NetworkImage(img1));
}
}
4、圆角
圆角 -- CircleAvatar:CircleAvatar 可以实现圆角头像,也可以添加一个子 Widget。
const CircleAvatar({
Key key,
// 子Widge
this.child,
// 背景颜色
this.backgroundColor,
// 背景图像
this.backgroundImage,
//
this.onBackgroundImageError,
// 前景颜色
this.foregroundColor,
// 半径
this.radius,
// 最小半径
this.minRadius,
// 最大半径
this.maxRadius,
})
示例
///圆角 -- CircleAvatar
class CircleImage extends StatelessWidget {
final String img1 =
'https://www.itying.com/themes/itying/images/ionic4.png';
const CircleImage({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: CircleAvatar(
radius: 100,
backgroundColor: Colors.grey,
backgroundImage: NetworkImage(img1),
child: Container(
alignment: const Alignment(0, .5),
width: 200,
height: 200,
child: const Text("星空")),
),
);
}
}
圆角 -- ClipOval
///圆角 -- ClipOval
class CircleImage2 extends StatelessWidget {
final String img1 =
'https://www.itying.com/themes/itying/images/ionic4.png';
const CircleImage2({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: ClipOval(
child: Image.network(
img1,
width: 200,
height: 200,
),
),
);
}
}
圆角 -- ClipRRect
///圆角 -- ClipRRect
class CircleImage3 extends StatelessWidget {
final String img1 =
'https://www.itying.com/themes/itying/images/ionic4.png';
const CircleImage3({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(100),
child: Image.network(
img1,
width: 200,
height: 200,
),
),
);
}
}
5、Icon 字体图标
Flutter 中的 Icon 为字体图标,有以下几个特点:
1、字体图标矢量图(放大不失真)。
2、字体图标可以设置颜色。
3、图标很多时,占据的空间更小。
示例
///Icon 字体图标
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const Center(
child: Column(
children: [
Icon(
Icons.search,
color: Colors.green,
size: 50,
),
SizedBox(
height: 10,
),
Icon(
Icons.home,
color: Colors.red,
size: 20,
),
SizedBox(
height: 10,
),
Icon(
Icons.category,
color: Colors.orange,
size: 10,
),
SizedBox(
height: 10,
),
Icon(
Icons.shop,
color: Colors.blue,
size: 30,
),
SizedBox(
height: 10,
),
Icon(
Icons.search_off,
color: Colors.black,
size: 50,
),
],
),
);
}
}
///利用字符显示图标,需指定 Unicode 编码及字体样式
class StringIcon extends StatelessWidget {
const StringIcon({super.key});
@override
Widget build(BuildContext context) {
return const Text(
'\ue567',
style: TextStyle(
fontFamily: 'MaterialIcons', color: Colors.blue, fontSize: 100),
);
}
}
3、TextField
const TextField({
Key key,
this.controller, //编辑框的控制器,跟文本框的交互一般都通过该属性完成,如果不创建的话默认会自动创建
this.focusNode, //用于管理焦点
this.decoration = const InputDecoration(), //输入框的装饰器,用来修改外观
TextInputType keyboardType, //设置输入类型,不同的输入类型键盘不一样
this.textInputAction, //用于控制键盘动作(一般位于右下角,默认是完成)
this.textCapitalization = TextCapitalization.none,
this.style, //输入的文本样式
this.textAlign = TextAlign.start, //输入的文本位置
this.textDirection, //输入的文字排列方向,一般不会修改这个属性
this.autofocus = false, //是否自动获取焦点
this.obscureText = false, //是否隐藏输入的文字,一般用在密码输入框中
this.autocorrect = true, //是否自动校验
this.maxLines = 1, //最大行
this.maxLength, //能输入的最大字符个数
this.maxLengthEnforced = true, //配合maxLength一起使用,在达到最大长度时是否阻止输入
this.onChanged, //输入文本发生变化时的回调
this.onEditingComplete, //点击键盘完成按钮时触发的回调,该回调没有参数,(){}
this.onSubmitted, //同样是点击键盘完成按钮时触发的回调,该回调有参数,参数即为当前输入框中的值。(String){}
this.inputFormatters, //对输入文本的校验
this.enabled, //输入框是否可用
this.cursorWidth = 2.0, //光标的宽度
this.cursorRadius, //光标的圆角
this.cursorColor, //光标的颜色
this.keyboardAppearance,
this.scrollPadding = const EdgeInsets.all(20.0),
this.dragStartBehavior = DragStartBehavior.down,
this.enableInteractiveSelection,
this.onTap, //点击输入框时的回调(){}
this.buildCounter,
})
InputDecoration
InputDecoration({
this.icon, //位于装饰器外部和输入框前面的图片
this.labelText, //用于描述输入框,例如这个输入框是用来输入用户名还是密码的,当输入框获取焦点时默认会浮动到上方,
this.labelStyle, // 控制labelText的样式,接收一个TextStyle类型的值
this.helperText, //辅助文本,位于输入框下方,如果errorText不为空的话,则helperText不会显示
this.helperStyle, //helperText的样式
this.hintText, //提示文本,位于输入框内部
this.hintStyle, //hintText的样式
this.hintMaxLines, //提示信息最大行数
this.errorText, //错误信息提示
this.errorStyle, //errorText的样式
this.errorMaxLines, //errorText最大行数
this.hasFloatingPlaceholder = true, //labelText是否浮动,默认为true,修改为false则labelText在输入框获取焦点时不会浮动且不显示
this.isDense, //改变输入框是否为密集型,默认为false,修改为true时,图标及间距会变小
this.contentPadding, //内间距
this.prefixIcon, //位于输入框内部起始位置的图标。
this.prefix, //预先填充的Widget,跟prefixText同时只能出现一个
this.prefixText, //预填充的文本,例如手机号前面预先加上区号等
this.prefixStyle, //prefixText的样式
this.suffixIcon, //位于输入框后面的图片,例如一般输入框后面会有个眼睛,控制输入内容是否明文
this.suffix, //位于输入框尾部的控件,同样的不能和suffixText同时使用
this.suffixText,//位于尾部的填充文字
this.suffixStyle, //suffixText的样式
this.counter,//位于输入框右下方的小控件,不能和counterText同时使用
this.counterText,//位于右下方显示的文本,常用于显示输入的字符数量
this.counterStyle, //counterText的样式
this.filled, //如果为true,则输入使用fillColor指定的颜色填充
this.fillColor, //相当于输入框的背景颜色
this.errorBorder, //errorText不为空,输入框没有焦点时要显示的边框
this.focusedBorder, //输入框有焦点时的边框,如果errorText不为空的话,该属性无效
this.focusedErrorBorder, //errorText不为空时,输入框有焦点时的边框
this.disabledBorder, //输入框禁用时显示的边框,如果errorText不为空的话,该属性无效
this.enabledBorder, //输入框可用时显示的边框,如果errorText不为空的话,该属性无效
this.border, //正常情况下的border
this.enabled = true, //输入框是否可用
this.semanticCounterText,
this.alignLabelWithHint,
})
示例
import 'package:flutter/material.dart';
main(List<String> args) {
runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('基本部件 - TextField'),
),
body: const Center(
child: TextFieldDemo(),
),
),
));
}
class TextFieldDemo extends StatefulWidget {
const TextFieldDemo({super.key});
@override
// ignore: library_private_types_in_public_api
_TextFieldDemoState createState() => _TextFieldDemoState();
}
class _TextFieldDemoState extends State<TextFieldDemo> {
final nameC = TextEditingController();
final passwordC = TextEditingController();
@override
Widget build(BuildContext context) {
return Column(
children: [
//姓名
UserNameField(nameC),
//密码
PasswordField(passwordC),
//登录
// ignore: sized_box_for_whitespace
Container(
width: 180,
height: 44,
child: TextButton(
style: ButtonStyle(
textStyle: MaterialStateProperty.all(const TextStyle()),
backgroundColor:
MaterialStateColor.resolveWith((states) => Colors.red),
),
onPressed: () {
// ignore: avoid_print
print('commit ${nameC.text}-${passwordC.text}');
},
child: const Text('登录'),
),
)
],
);
}
}
// ignore: must_be_immutable
class UserNameField extends StatelessWidget {
late TextEditingController userNameController;
UserNameField(TextEditingController controller, {super.key}) {
userNameController = controller;
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(18),
child: TextField(
controller: userNameController,
decoration: InputDecoration(
labelText: '姓名',
hintText: '请输入',
hintStyle: const TextStyle(color: Colors.green),
icon: const Icon(Icons.people),
border: const OutlineInputBorder(
borderSide: BorderSide(
color: Colors.red, width: 0.1, style: BorderStyle.none)),
filled: true,
fillColor: Colors.lightGreen[50], // 需设置filled为true才可生效
hoverColor: Colors.red,
),
onChanged: (value) {
// ignore: avoid_print
print('姓名: $value');
},
onSubmitted: (value) {
// ignore: avoid_print
print('姓名提交: $value');
},
),
);
}
}
// ignore: must_be_immutable
class PasswordField extends StatelessWidget {
late TextEditingController passwordController;
PasswordField(TextEditingController controller, {super.key}) {
passwordController = controller;
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(18),
child: TextField(
controller: passwordController,
decoration: InputDecoration(
labelText: '密码',
hintText: '请输入',
hintStyle: const TextStyle(color: Colors.green),
icon: const Icon(Icons.lock),
border: const OutlineInputBorder(
borderSide: BorderSide(
color: Colors.red, width: 0.1, style: BorderStyle.none)),
filled: true,
fillColor: Colors.lightGreen[50], // 需设置filled为true才可生效
hoverColor: Colors.red,
),
onChanged: (value) {
// ignore: avoid_print
print('密码: $value');
},
onSubmitted: (value) {
// ignore: avoid_print
print('密码提交: $value');
},
),
);
}
}