最近做flutter web正好有这个需求,就随手找了找,最终看上了inkwell,(inkwell不只是水波纹啊喂)
基本思路就是调用inkwell的onhover方法对鼠标事件进行监听,状态管理用的getx,代码:

view:(也算是封装了个组件)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import 'logic.dart';

class BasicCard extends StatelessWidget {
final basicCardLogic = Get.put(BasicCardLogic());

final ShapeBorder? shape;
final EdgeInsetsGeometry? margin;
final Widget? child;


BasicCard({
this.shape,
this.margin,
this.child
});

@override
Widget build(BuildContext context) {
return GetBuilder<BasicCardLogic>(
builder: (logic)=>
InkWell(
onTap: (){},
child: Card(
elevation: basicCardLogic.elevation.value,
shape: shape,
margin: margin,
child: child,
),
onHover: (value){
value ? basicCardLogic.cursorMoveIn() : basicCardLogic.cursorMoveOut();
},
),
);
}
}

logic&binding

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import 'package:get/get.dart';

class BasicCardLogic extends GetxController {
RxDouble elevation = 1.0.obs;

void cursorMoveIn(){
elevation.value = 5.0;
}
void cursorMoveOut(){
elevation.value = 1.0;
}
}
class BasicCardBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut(() => BasicCardLogic());
}
}

踩坑:

inkwell如果没写onTap方法的那个匿名函数会导致onHover无效。

9.28更新:

干掉了inkwell的自带阴影,另外提供了另一种实现方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@override
Widget build(BuildContext context) {
return GetBuilder<BasicCardLogic>(
builder: (logic) =>InkWell(
focusColor: MyTheme.transparent,
hoverColor: MyTheme.transparent,
highlightColor: MyTheme.transparent,
splashColor: MyTheme.transparent,
onTap: (){},
child: Container(
child: Card(
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))), //设置圆角
elevation: basicCardLogic.elevation.value,
margin: margin,
child: child,
),
// decoration: BoxDecoration(
// borderRadius: BorderRadius.all(Radius.circular(8)),
// boxShadow: [
// BoxShadow(
// color: basicCardLogic.cursorIn.value ? Colors.black45 : Colors.black12, //底色,阴影颜色
// offset: Offset(4, 4), //阴影位置,从什么位置开始
// blurRadius: 16, // 阴影模糊层度
// spreadRadius: 0, //阴影模糊大小
// )],
// )
),
onHover: (value){
value ? basicCardLogic.cursorMoveIn() : basicCardLogic.cursorMoveOut();
},
),
);
}

12.16更新:

getBuilder有异常导致出现UI问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

@override
Widget build(BuildContext context) {
return InkWell(
// focusColor: Colors.transparent,
// hoverColor: Colors.transparent,
// highlightColor: Colors.transparent,
// splashColor: Colors.transparent,
onTap: (){},
child: Container(
child:Obx(()=>Card(
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))), //设置圆角
elevation: basicCardLogic.elevation.value,
margin: margin,
child: child,
),)

// decoration: BoxDecoration(
// borderRadius: BorderRadius.all(Radius.circular(8)),
// boxShadow: [
// BoxShadow(
// color: basicCardLogic.cursorIn.value ? Colors.black45 : Colors.black12, //底色,阴影颜色
// offset: Offset(4, 4), //阴影位置,从什么位置开始
// blurRadius: 16, // 阴影模糊层度
// spreadRadius: 0, //阴影模糊大小
// )],
// )
),
onHover: (value){
value ? basicCardLogic.cursorMoveIn() : basicCardLogic.cursorMoveOut();
},
);
}

12.19更新:

发现如果一个界面中有多个basicCard,在鼠标移入时都会变色,(我不李姐)。理论上讲多个baseCard是多个不同的对象,他们的logic应该是各自独立的才对,但其表现出来的现象却让人觉得这几个logic是一样的。后期发现确实只有一个card响应了鼠标移入事件,但是所有的卡片也确实都变色了。于是更新,直接弃用了getx,改用了StatefulWidget

又:只有onTap方法传入的时候onHover才有效,原因未知。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import 'package:flutter/material.dart';

class BasicCard extends StatefulWidget {

final ShapeBorder? shape;
final EdgeInsetsGeometry? margin;
final Widget child;
final Function() onTap;

BasicCard({
this.shape,
this.margin,
required this.child,
required this.onTap
});

@override
_BasicCardState createState() =>_BasicCardState();
}
class _BasicCardState extends State<BasicCard>{
Color cardColor = Colors.white;

@override
Widget build(BuildContext context) {
return InkWell(
focusColor: Colors.transparent,
hoverColor: Colors.transparent,
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
onTap: widget.onTap,
child: Container(
child:Card(
color: cardColor,
shape:widget.shape==null ? RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0))):widget.shape, //设置圆角
// elevation: basicCardLogic.elevation.value,
margin: widget.margin,
child: widget.child,
),
),
onHover: (value){
setState(() {
cardColor = value ? Colors.blue : Colors.white;
});

},
);
}
}