在 Flutter 中创建带有图像的按钮?
Create a button with an image in Flutter?
如何使用 Flutter 创建带有图像的按钮?这似乎是最简单的事情,但图像并没有完全填满父窗口小部件。这是我的:
Container(child: ConstrainedBox(
constraints: BoxConstraints.expand(),
child: FlatButton(onPressed: null,
child: Image.asset('path/the_image.png'))))
我遵循 作为指导。我的图像是这样的:
注意 PNG 图像周围的填充 - 它不在代码中。它从何而来? PNG 本身没有 canvas 填充,因此这一定不是正确的技术。
我只需要一个带有填充整个 FlatButton
图像的按钮,或者另一个我可以添加操作的小部件,而不会扭曲图像。
在 FlatButton
中放置图像可能不符合您的要求,因为它会自行处理一些样式(例如填充)。
要完全控制按钮方面,您可能需要构建自定义小部件(即使是简单的 Container
和自定义 BoxDecoration
来显示图像)并用手势识别器包装它处理用户交互(在您的情况下,只需点击一下)。最简单的实现是使用 GestureDetector
,但也有其他小部件,例如 InkWell
,它在点击时在可点击小部件表面呈现 material 设计涟漪。
我认为这也应该有效。
只需将 FlatButton 的填充指定为零。
Container(child: ConstrainedBox(
constraints: BoxConstraints.expand(),
child: FlatButton(
onPressed: null,
padding: EdgeInsets.all(0.0),
child: Image.asset('path/the_image.png'))))
显示图像图标按钮,按下时在图像上产生波纹效果:
Material(
// needed
color: Colors.transparent,
child: InkWell(
onTap: () => myOnTap, // needed
child: Image.asset(
"assets/resize.png",
width: 22,
fit: BoxFit.cover,
),
),
)
我认为,使用 GestureDetector 是更简单也是最通用的方法,因为它允许您为不同的手势调用不同的函数,例如单击、双击、长按等。
GestureDetector(
onTap: () => _yourFunction('yourParameter'),
child: Image.asset('yourimagefolder/yourimage.png'),
),
IconButton(
icon: Image.asset('path/the_image.png'),
iconSize: 50,
onPressed: () {},
)
像这样将您的图片放在 gestureDetector
中:
GestureDetector(
onTap: () {}
child: Image.asset('path/the_image.png')
)
您可以使用 Stack 轻松做到这一点
Stack(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height / 3.6,
width: MediaQuery.of(context).size.width / 2.2,
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child:imageLoader1(img),
/* Image.asset(
"$img",
fit: BoxFit.cover,
),*/
),
),
Positioned(
right: -10.0,
bottom: 3.0,
child: RawMaterialButton(
onPressed: (){},
fillColor: Colors.white,
shape: CircleBorder(),
elevation: 4.0,
child: Padding(
padding: EdgeInsets.all(5),
child: Icon(
isFav
?Icons.favorite
:Icons.favorite_border,
color: Colors.red,
size: 17,
),
),
),
),
],
),
GestureDetector(
onTap: () {print('click on edit');},
child: Image(
image: AssetImage('assets/images/icons/edit-button.png'),
fit: BoxFit.cover,
height: 20,
)
),
带有波纹效果和底部文本的图像按钮
(当然你可以去掉text部分和Stack)
Material(
elevation: 4.0,
clipBehavior: Clip.hardEdge,
color: Colors.transparent,
child: Stack(
alignment: Alignment.bottomCenter,
fit: StackFit.passthrough,
children: [
Ink.image(
image: AssetImage(imagePath),
fit: BoxFit.cover,
width: 120,
height: 120,
child: InkWell(onTap: () {}),
),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(label, style: const TextStyle(fontSize: 20)),
),
)
],
),
);
截图:
代码:
InkWell(
onTap: () {}, // Handle your callback.
splashColor: Colors.brown.withOpacity(0.5),
child: Ink(
height: 100,
width: 100,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('your_image_asset'),
fit: BoxFit.cover,
),
),
),
)
我正在创建自己的墨水瓶,它有带子元素的三重动画和 onPress 回调 用于像图像这样的非透明背景
class InkWellApp extends StatelessWidget {
final Function onTap;
final Widget child;
final EdgeInsets margin;
final BorderRadius borderRadius;
const InkWellApp(
{Key key,
this.onTap,
this.child,
this.borderRadius = BorderRadius.zero,
this.margin = EdgeInsets.zero})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container(
margin: margin,
child: Stack(
children: [
child,
Positioned.fill(
child: Material(
color: Colors.transparent,
borderRadius: borderRadius,
child: InkWell(
borderRadius: borderRadius,
onTap: onTap,
),
),
),
],
),
);
}
}
然后您可以在应用程序中将它与任何像这样的小部件或图像一起使用
InkWellApp(
onTap: (){
//your code here
},
child: yourWidget,
),
Note : borderRadius and margin is optional parameters
为此可以使用 TextButton。
TextButton.icon(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.white)),
onPressed: () {},
icon: Image.asset('path/the_image.png'),
label: Text(
'Button Text',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
)
FlatButton(
onPressed: (){},
color: Colors.orange,
padding: EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
Image.asset(name),
Text("Add")
],
);
您可以添加图标和图片
如果你有一个圆角矩形按钮然后按照下面的代码
TextButton(
style: TextButton.styleFrom(
alignment: Alignment.topLeft,
backgroundColor: Colors.lightBlue,
minimumSize: const Size(double.infinity, 200),
padding: const EdgeInsets.all(0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
),
onPressed: () => null,
child: SizedBox(
height: 100,
width: 500,
child: Stack(
children: [
**Positioned(
top: 0,
left: 0,
right: 0,**
child: ClipRRect(
borderRadius: const BorderRadius.vertical(
top: Radius.circular(20),
),
child: Image.asset(
'assets/miniMartGrocery.png',
fit: BoxFit.cover,
),
),
),
Positioned(
top: 10,
left: screenSize.width * 0.84,
child: Container(
width: 40,
height: 40,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(100),
color: Colors.white),
child: IconButton(
icon: Icon(
FontAwesomeIcons.flag,
),
onPressed: () => null,
),
))
],
),
),
),
如何使用 Flutter 创建带有图像的按钮?这似乎是最简单的事情,但图像并没有完全填满父窗口小部件。这是我的:
Container(child: ConstrainedBox(
constraints: BoxConstraints.expand(),
child: FlatButton(onPressed: null,
child: Image.asset('path/the_image.png'))))
我遵循
注意 PNG 图像周围的填充 - 它不在代码中。它从何而来? PNG 本身没有 canvas 填充,因此这一定不是正确的技术。
我只需要一个带有填充整个 FlatButton
图像的按钮,或者另一个我可以添加操作的小部件,而不会扭曲图像。
在 FlatButton
中放置图像可能不符合您的要求,因为它会自行处理一些样式(例如填充)。
要完全控制按钮方面,您可能需要构建自定义小部件(即使是简单的 Container
和自定义 BoxDecoration
来显示图像)并用手势识别器包装它处理用户交互(在您的情况下,只需点击一下)。最简单的实现是使用 GestureDetector
,但也有其他小部件,例如 InkWell
,它在点击时在可点击小部件表面呈现 material 设计涟漪。
我认为这也应该有效。 只需将 FlatButton 的填充指定为零。
Container(child: ConstrainedBox(
constraints: BoxConstraints.expand(),
child: FlatButton(
onPressed: null,
padding: EdgeInsets.all(0.0),
child: Image.asset('path/the_image.png'))))
显示图像图标按钮,按下时在图像上产生波纹效果:
Material(
// needed
color: Colors.transparent,
child: InkWell(
onTap: () => myOnTap, // needed
child: Image.asset(
"assets/resize.png",
width: 22,
fit: BoxFit.cover,
),
),
)
我认为,使用 GestureDetector 是更简单也是最通用的方法,因为它允许您为不同的手势调用不同的函数,例如单击、双击、长按等。
GestureDetector(
onTap: () => _yourFunction('yourParameter'),
child: Image.asset('yourimagefolder/yourimage.png'),
),
IconButton(
icon: Image.asset('path/the_image.png'),
iconSize: 50,
onPressed: () {},
)
像这样将您的图片放在 gestureDetector
中:
GestureDetector(
onTap: () {}
child: Image.asset('path/the_image.png')
)
您可以使用 Stack 轻松做到这一点
Stack(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height / 3.6,
width: MediaQuery.of(context).size.width / 2.2,
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child:imageLoader1(img),
/* Image.asset(
"$img",
fit: BoxFit.cover,
),*/
),
),
Positioned(
right: -10.0,
bottom: 3.0,
child: RawMaterialButton(
onPressed: (){},
fillColor: Colors.white,
shape: CircleBorder(),
elevation: 4.0,
child: Padding(
padding: EdgeInsets.all(5),
child: Icon(
isFav
?Icons.favorite
:Icons.favorite_border,
color: Colors.red,
size: 17,
),
),
),
),
],
),
GestureDetector(
onTap: () {print('click on edit');},
child: Image(
image: AssetImage('assets/images/icons/edit-button.png'),
fit: BoxFit.cover,
height: 20,
)
),
带有波纹效果和底部文本的图像按钮
(当然你可以去掉text部分和Stack)
Material(
elevation: 4.0,
clipBehavior: Clip.hardEdge,
color: Colors.transparent,
child: Stack(
alignment: Alignment.bottomCenter,
fit: StackFit.passthrough,
children: [
Ink.image(
image: AssetImage(imagePath),
fit: BoxFit.cover,
width: 120,
height: 120,
child: InkWell(onTap: () {}),
),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(label, style: const TextStyle(fontSize: 20)),
),
)
],
),
);
截图:
代码:
InkWell(
onTap: () {}, // Handle your callback.
splashColor: Colors.brown.withOpacity(0.5),
child: Ink(
height: 100,
width: 100,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('your_image_asset'),
fit: BoxFit.cover,
),
),
),
)
我正在创建自己的墨水瓶,它有带子元素的三重动画和 onPress 回调 用于像图像这样的非透明背景
class InkWellApp extends StatelessWidget {
final Function onTap;
final Widget child;
final EdgeInsets margin;
final BorderRadius borderRadius;
const InkWellApp(
{Key key,
this.onTap,
this.child,
this.borderRadius = BorderRadius.zero,
this.margin = EdgeInsets.zero})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container(
margin: margin,
child: Stack(
children: [
child,
Positioned.fill(
child: Material(
color: Colors.transparent,
borderRadius: borderRadius,
child: InkWell(
borderRadius: borderRadius,
onTap: onTap,
),
),
),
],
),
);
}
}
然后您可以在应用程序中将它与任何像这样的小部件或图像一起使用
InkWellApp(
onTap: (){
//your code here
},
child: yourWidget,
),
Note : borderRadius and margin is optional parameters
为此可以使用 TextButton。
TextButton.icon(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.white)),
onPressed: () {},
icon: Image.asset('path/the_image.png'),
label: Text(
'Button Text',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
),
)
FlatButton(
onPressed: (){},
color: Colors.orange,
padding: EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
Image.asset(name),
Text("Add")
],
);
您可以添加图标和图片
如果你有一个圆角矩形按钮然后按照下面的代码
TextButton(
style: TextButton.styleFrom(
alignment: Alignment.topLeft,
backgroundColor: Colors.lightBlue,
minimumSize: const Size(double.infinity, 200),
padding: const EdgeInsets.all(0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
),
onPressed: () => null,
child: SizedBox(
height: 100,
width: 500,
child: Stack(
children: [
**Positioned(
top: 0,
left: 0,
right: 0,**
child: ClipRRect(
borderRadius: const BorderRadius.vertical(
top: Radius.circular(20),
),
child: Image.asset(
'assets/miniMartGrocery.png',
fit: BoxFit.cover,
),
),
),
Positioned(
top: 10,
left: screenSize.width * 0.84,
child: Container(
width: 40,
height: 40,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(100),
color: Colors.white),
child: IconButton(
icon: Icon(
FontAwesomeIcons.flag,
),
onPressed: () => null,
),
))
],
),
),
),