Flutter移动端使用Matrix4.identity()..translate时应用崩溃问题
我制作了一个包裹在MouseRegion组件中的按钮,通过Matrix4.identity()..translate(0,-10,0)实现悬浮效果,该效果在Web端正常运行,但在移动设备上运行时应用崩溃,报错信息如下:
═══════ Exception caught by widgets library ═══════════════════════════════════
The following UnimplementedError was thrown building OnHover(dirty, state: _OnHoverState#9e2af):
UnimplementedError
The relevant error-causing widget was
OnHover
lib\main.dart:7
When the exception was thrown, this was the stack
#0 Matrix4.translate
package:vector_math/…/vector_math_64/matrix4.dart:682
#1 _OnHoverState.build\
相关代码如下:
import 'package:flutter/material.dart'; class OnHover extends StatefulWidget { final Widget Function(bool isHovered) builder; const OnHover({Key? key, required this.builder}) : super(key: key); @override _OnHoverState createState() => _OnHoverState(); } class _OnHoverState extends State<OnHover> { bool isHovered = false; @override Widget build(BuildContext context) { final hovered = Matrix4.identity()..translate(0,-10,0); final transform = isHovered ? hovered : Matrix4.identity(); return MouseRegion( onEnter: (_)=> onEntered(true), onExit: (_)=> onEntered(false), child: AnimatedContainer( duration: Duration(milliseconds: 300), transform: transform, child: widget.builder(isHovered), ), ); } void onEntered(bool isHovered){ setState(() { this.isHovered = isHovered; }); } }
问题原因
移动端平台上,Matrix4.translate方法存在未实现的情况,直接使用级联调用..translate会触发UnimplementedError。
解决方法
替换Matrix4.identity()..translate(0,-10,0)的写法,改用Matrix4.translationValues来创建平移矩阵,这个方法在全平台都已实现:
修改后的核心代码片段
// 替换原来的hovered定义 final hovered = Matrix4.translationValues(0, -10, 0); final transform = isHovered ? hovered : Matrix4.identity();
完整修改后的组件代码
import 'package:flutter/material.dart'; class OnHover extends StatefulWidget { final Widget Function(bool isHovered) builder; const OnHover({Key? key, required this.builder}) : super(key: key); @override _OnHoverState createState() => _OnHoverState(); } class _OnHoverState extends State<OnHover> { bool isHovered = false; @override Widget build(BuildContext context) { final hovered = Matrix4.translationValues(0, -10, 0); final transform = isHovered ? hovered : Matrix4.identity(); return MouseRegion( onEnter: (_)=> onEntered(true), onExit: (_)=> onEntered(false), child: AnimatedContainer( duration: Duration(milliseconds: 300), transform: transform, child: widget.builder(isHovered), ), ); } void onEntered(bool isHovered){ setState(() { this.isHovered = isHovered; }); } }
额外优化:移动端交互适配
MouseRegion在移动端不会触发hover事件,若需要在移动端实现类似的触摸反馈,可添加GestureDetector处理触摸事件:
return MouseRegion( onEnter: (_)=> onEntered(true), onExit: (_)=> onEntered(false), child: GestureDetector( onTapDown: (_) => onEntered(true), onTapUp: (_) => onEntered(false), onTapCancel: () => onEntered(false), child: AnimatedContainer( duration: Duration(milliseconds: 300), transform: transform, child: widget.builder(isHovered), ), ), );
内容的提问来源于stack exchange,提问作者Dhruv409

