最近做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, ), ), 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( onTap: (){}, child: Container( child:Obx(()=>Card( shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))), elevation: basicCardLogic.elevation.value, margin: margin, child: child, ),)
), 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, margin: widget.margin, child: widget.child, ), ), onHover: (value){ setState(() { cardColor = value ? Colors.blue : Colors.white; });
}, ); } }
|