Flutter Draggable与DragTarget的onWillAccept、onAccept参数使用问题
问题根因
- Draggable未配置
data属性:你声明了Draggable<String>类型,但没有给data参数传值,DragTarget接收拖拽数据时拿到的永远是null,onWillAccept判断自然无法通过。 - 后续修改类型错配:把DragTarget泛型改成
DragBox属于错误操作,首先Draggable的泛型是String,类型不匹配会导致拿到的data始终为null;其次就算传递DragBox实例,两个不同的DragBox(letter: letter)实例用==判断默认是引用对比,永远返回false,不可能匹配成功。
修复方案
1. 给Draggable补充data参数
修改DragBox类的Draggable配置,把当前字母作为拖拽传递的数据:
class DragBox extends StatelessWidget { const DragBox({ required this.letter, }); final String letter; @override Widget build(BuildContext context) { return Draggable<String>( // 补上data参数,传递当前字母 data: letter, feedback: LetterBox(letter: letter), child: LetterBox(letter: letter), childWhenDragging: LetterBox(letter: ' '), ); } }
2. 还原DragTarget的配置
改回最初的DragTarget<String>即可,原有的onWillAccept逻辑是正确的:
class TargetBox extends StatelessWidget { const TargetBox({ required this.letter, }); final String letter; @override Widget build(BuildContext context) { return DragTarget<String>( builder: (context, candidateData, rejectedData) { // 可选优化:有匹配的拖拽元素时显示目标字母做提示 return LetterBox(letter: candidateData.isNotEmpty ? letter : ' '); }, onWillAccept: (data) => data == letter, onAccept: (data) { print('接收成功,拖拽字母:$data,目标字母:$letter'); }, onLeave: (data) { print('拖拽离开,携带数据:$data'); }); } }
3. 可选优化
你当前把letters.shuffle()写在build方法里,每次setState都会重新打乱字母顺序,建议把初始化逻辑移到initState中避免逻辑异常:
class _AnagramState extends State<Anagram> { late List<String> letters; @override void initState() { super.initState(); letters = widget.word!.split(""); letters.shuffle(); } @override Widget build(BuildContext context) { // 原有布局代码不变,删除build方法里的letters初始化、shuffle逻辑 return Scaffold( // 原有代码不变 ); } }
内容的提问来源于stack exchange,提问作者SylvainJack
相关产品推荐
相关产品推荐

