【发布时间】:2020-05-20 10:34:57
【问题描述】:
我是一名 JavaScript 开发人员,并且是 Flutter 的新手。我只想使用 Flutter for Web 在鼠标悬停时为一组图像设置动画,例如 this。它包括缩放、不透明度和灰度转换。如何在 Flutter 中实现这一点? 提前致谢。
【问题讨论】:
标签: flutter flutter-animation flutter-web
我是一名 JavaScript 开发人员,并且是 Flutter 的新手。我只想使用 Flutter for Web 在鼠标悬停时为一组图像设置动画,例如 this。它包括缩放、不透明度和灰度转换。如何在 Flutter 中实现这一点? 提前致谢。
【问题讨论】:
标签: flutter flutter-animation flutter-web
除了您问题的动画部分。 InkWell 的 onHover 参数仅在您先指定 onTap 参数时才有效。
InkWell(
child: SomeWidget(),
onTap: () {
//You can leave it empty, like that.
}
onHover: (isHovering) {
if (isHovering) {
//The mouse is hovering.
} else {
//The mouse is no longer hovering.
}
}
)
从documentation,这里是boolean 的好处,它被传递给onHover 回调:
如果指针已经进入这部分,则传递给回调的值为真 材质,如果指针已退出材质的这一部分,则返回 false。
【讨论】:
这只是一个演示,显示您可以使用onHover 或Inkwell 小部件来完成任务。您必须想出逻辑来决定应该使用多少偏移量和比例以及如何定位小部件。在我的示例中,我使用了网格视图。您也许可以使用堆栈根据悬停设置当前活动的小部件。
这里是一个网格视图的例子。此dartpad 中提供了此版本的实时版本。
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GridView.count(
crossAxisCount: 3,
children: <Widget>[ImageHover(),ImageHover(),ImageHover(),ImageHover(),ImageHover(),ImageHover(),ImageHover(),],
);
}
}
class ImageHover extends StatefulWidget {
@override
_ImageHoverState createState() => _ImageHoverState();
}
class _ImageHoverState extends State<ImageHover> {
double elevation = 4.0;
double scale = 1.0;
Offset translate = Offset(0,0);
@override
Widget build(context) {
return InkWell(
onTap: (){},
onHover: (value){
print(value);
if(value){
setState((){
elevation = 20.0;
scale = 2.0;
translate = Offset(20,20);
});
}else{
setState((){
elevation = 4.0;
scale = 1.0;
translate = Offset(0,0);
});
}
},
child: Transform.translate(
offset: translate ,
child: Transform.scale(
scale: scale,
child: Material(
elevation: elevation,
child: Image.network(
'https://i.ytimg.com/vi/acm9dCI5_dc/maxresdefault.jpg',
),
),
),
),
);
}
}
【讨论】:
只需创建一个扩展程序
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
extension HoverExtension on Widget {
Widget get translateOnHover {
return kIsWeb ? TranslateOnHover(child: this) : ThisContainer(child: this);
}
}
class ThisContainer extends StatelessWidget {
ThisContainer({this.child});
final child;
@override
Widget build(BuildContext context) {
return Container(child: child);
}
}
class TranslateOnHover extends StatefulWidget {
final Widget child;
TranslateOnHover({required this.child});
@override
_TranslateOnHoverState createState() => _TranslateOnHoverState();
}
class _TranslateOnHoverState extends State<TranslateOnHover> {
double scale = 1.0;
@override
Widget build(BuildContext context) {
return MouseRegion(
onEnter: (e) => _mouseEnter(true),
onExit: (e) => _mouseEnter(false),
child: TweenAnimationBuilder(
duration: const Duration(milliseconds: 200),
tween: Tween<double>(begin: 1.0, end: scale),
builder: (BuildContext context, double value, _) {
return Transform.scale(scale: value, child: widget.child);
},
),
);
}
void _mouseEnter(bool hover) {
setState(() {
if (hover)
scale = 1.03;
else
scale = 1.0;
});
}
}
并通过调用在任何地方使用它
yourWidget.translateOnHover
【讨论】: