Flutter中ReorderableListView.builder无法实现重排如何解决?
问题原因排查
- 状态变量定义位置错误
你将存储列表数据的list变量直接定义在build方法内部,每次setState触发组件重绘时,build方法都会重新执行,list会被重置为初始的['1','2'...'10']数组,你在拖拽逻辑中对list的修改会被直接覆盖,自然看不到UI更新。 - 列表项Key绑定错误
你给每个Card指定的key是ValueKey(index),拖拽排序后对应位置的index会发生变化,Flutter通过Key判断组件是否需要更新时会出现匹配错误,需要将Key和列表项本身的唯一值绑定。
修复方案
将list变量提升为_CardsState类的成员变量,不要放在build方法内,同时修改Key的取值为列表项的值,修复后的完整代码如下:
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class Mainpage extends StatefulWidget { const Mainpage({Key? key}) : super(key: key); @override _MainpageState createState() => _MainpageState(); } class _MainpageState extends State<Mainpage> { @override void initState() { super.initState(); SystemChrome.setPreferredOrientations( [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]); } @override Widget build(BuildContext context) { return Container(color: Colors.white, child: const Cards()); } } class Cards extends StatefulWidget { const Cards({Key? key}) : super(key: key); @override State<Cards> createState() => _CardsState(); } class _CardsState extends State<Cards> { // 把list提升为类的成员变量 List<String> list = [ '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', ]; @override Widget build(BuildContext context) { return Container( color: Colors.white, child: ReorderableListView.builder( padding: const EdgeInsets.fromLTRB(20, 0, 20, 0), scrollDirection: Axis.horizontal, onReorder: (int oldIndex, int newIndex) { setState(() { if (oldIndex < newIndex) { newIndex--; } final String item = list.removeAt(oldIndex); list.insert(newIndex, item); }); }, itemBuilder: (BuildContext context, int index) { return Card( // key修改为和元素值绑定 key: ValueKey(list[index]), child: Container( height: MediaQuery.of(context).size.height / 4, width: MediaQuery.of(context).size.width / 19, alignment: Alignment.bottomCenter, child: Text(list[index]), ), ); }, itemCount: list.length, )); } }
提示:如果实际业务中列表项存在重复值,可以给每个元素设置唯一id,将key和id绑定即可。
内容的提问来源于stack exchange,提问作者Joshua Jenny Sibbu
相关产品推荐
相关产品推荐

