移除Flutter中ReorderableListView拖拽时的矩形阴影
Flutter ReorderableListView拖拽时圆角元素出现矩形阴影问题解决
我在TODO应用中使用ReorderableListView实现了可拖拽排序的ListaItem元素,该元素本身带有圆角边框,但拖拽时会出现难看的矩形阴影,目标是移除这个阴影。
正常显示效果


ListaItem代码
@override Widget build(BuildContext context) { return Container( margin: EdgeInsets.only(left:10.0, right: 10.0, top: 7,bottom: 7), decoration: BoxDecoration( boxShadow: [BoxShadow( color: Color.fromRGBO(50, 50, 50, 0.21), offset: Offset(2, 2), blurRadius: 10.0 )], borderRadius: BorderRadius.all(Radius.circular(100.0)) ), child: ElevatedButton( onPressed: () { setState(() { widget.checkValue = !widget.checkValue; }); }, style: ElevatedButton.styleFrom( primary: Colors.white, onPrimary: Color.fromARGB(0, 59, 59, 59), shape: StadiumBorder(), ), child: AnimatedContainer( duration: Duration(milliseconds: 100), height: 55, padding: EdgeInsets.only(left: 10, right: 2), child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( widget.product, style: TextStyle( color: widget.checkValue ? Color.fromARGB(120, 37, 37, 37) : Color.fromARGB(200, 37, 37, 37), fontSize: 20, fontWeight: FontWeight.w300, decoration: widget.checkValue ? TextDecoration.lineThrough : TextDecoration.none ), ), newCheck(value: widget.checkValue)//自定义样式复选框 ], ), ) ), ); }
拖拽时的问题效果

ReorderableListView代码
@override Widget build(BuildContext context) { var Items = new List<Item>.generate(10, (i) => Item(i, i.toString())); return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Container( color: Colors.transparent, child: Expanded( child: ReorderableListView( padding: EdgeInsets.only(top:20), onReorder: ((oldIndex, newIndex) { }), children: [ for(int i = 0; i < Items.length; i++) ListaItem(checkValue: Items[i].state, product: Items[i].title,key: Key(i.toString()),) ], ) ) ), ), // 尾部逗号使build方法自动格式化更美观 ); }
解决方案
问题根源是ReorderableListView在拖拽时会默认给选中元素添加一个未适配圆角的矩形阴影,可通过以下两种方式解决:
方法一:自定义拖拽代理样式(推荐)
在ReorderableListView中添加proxyDecorator参数,自定义拖拽时的元素外观,覆盖默认阴影:
ReorderableListView( padding: EdgeInsets.only(top:20), onReorder: ((oldIndex, newIndex) { // 实现你的排序逻辑 }), // 自定义拖拽代理样式 proxyDecorator: (Widget child, int index, Animation<double> animation) { return Material( color: Colors.transparent, child: child, ); }, children: [ for(int i = 0; i < Items.length; i++) ListaItem(checkValue: Items[i].state, product: Items[i].title,key: Key(i.toString()),) ], )
proxyDecorator允许你完全控制拖拽时显示的元素,这里用透明背景的Material包裹原元素,直接消除默认的矩形阴影。
方法二:裁剪阴影适配圆角
通过ClipRRect包裹ListaItem的Container,确保阴影跟随圆角裁剪:
@override Widget build(BuildContext context) { return ClipRRect( borderRadius: BorderRadius.all(Radius.circular(100.0)), child: Container( margin: EdgeInsets.only(left:10.0, right: 10.0, top: 7,bottom: 7), decoration: BoxDecoration( boxShadow: [BoxShadow( color: Color.fromRGBO(50, 50, 50, 0.21), offset: Offset(2, 2), blurRadius: 10.0 )], borderRadius: BorderRadius.all(Radius.circular(100.0)) ), child: ElevatedButton( // 原按钮代码不变 ), ), ); }
这种方式会裁剪Container的阴影,使其贴合圆角,但不如第一种方法直接解决拖拽时的默认阴影问题。
内容的提问来源于stack exchange,提问作者GabryLinux
相关产品推荐
相关产品推荐

