前言
在我们日常开发中,使用 GridView
这种网格视图的场合还是不少的,比如照片墙、九宫格等等。有一个场景就是需要对网格的元素进行拖拽排序,这个时候 Flutter 自带的GridView
就无法满足了。本篇我们来介绍一个支持拖拽的 GridView
组件,可以轻松搞定网格视图的拖拽排序,这个组件就是 flutter_draggable_gridview
。
GraggableGridView 使用
flutter_draggable_gridview
使用一个DraggableGridViewBuilder
来构建可拖拽的 GridView
,内部实际上还是基于 GridView
实现的,因此 GridView
的一些配置还是可以沿用。DraggableGridViewBuilder
的一些特有的属性如下:
chidren
:要求返回的子组件列表需要是DraggableGridItem
,实际上我们可以用DraggableGridItem
来包裹我们要展示的元素即可。isOnlyLongPress
:是否只有长按才能触发拖拽,默认是true
。dragCompletion
:完成拖拽后的回调,会告诉我们哪两个元素进行了位置互换,通过互换的元素的下标我们可以知道拖拽后的次序。如果需要保存的话就可以提交拖拽后的次序到后端更新。dragFeedback
:一个回调函数,当拖拽开始后可以返回一个组件,来突显正在被控制拖动的元素。通常是将原先的组件尺寸缩小。dragPlaceHolder
:元素被拖动后,留下的空白位置的占位组件,可以自定义任何组件。
正常使用的时候,基本上我们把这些属性设置好就能用了。比如下面的代码:
DraggableGridViewBuilder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 3),
),
children: _makeGridItems(12),
isOnlyLongPress: true,
dragCompletion:
(List<DraggableGridItem> list, int beforeIndex, int afterIndex) {
if (kDebugMode) {
print('onDragAccept: $beforeIndex -> $afterIndex');
}
},
dragFeedback: (List<DraggableGridItem> list, int index) {
return SizedBox(
width: 200,
height: 150,
child: list[index].child,
);
},
dragStartBehavior: DragStartBehavior.start,
dragPlaceHolder: (List<DraggableGridItem> list, int index) {
return PlaceHolderWidget(
child: Container(
color: Colors.blue[100],
),
);
},
)
这里的_makeGridItems
方法就是构建子元素列表的方法,实际上就是用DraggableGridItem
包裹一层要显示的组件。
List<DraggableGridItem> _makeGridItems(int count) {
var colors = [
Colors.blue,
Colors.red[400],
Colors.amber,
Colors.orange,
Colors.purple
];
return List.generate(
count,
(index) => DraggableGridItem(
isDraggable: true,
child: Container(
color: colors[index % colors.length],
child: Center(
child: Material(
color: Colors.transparent,
child: Text('$index'),
),
),
),
),
);
}
DraggableGridItem
还有两个参数可以供我们使用:
isDraggable
:是否可以拖拽, 默认是false
,比如我们有些元素是固定不可以改变的(如置顶元素),那么就可以设置为false
。dragCallback
:在拖拽过程中,当一个元素正在被推挤时,回调函数中的第二个参数isDragging
会为true
。我们可以通过这个参数来做一些处理,比如高亮当前被推挤的元素。
我们有了上面的框架后,大部分情况下,只需要控制要显示的子元素和尺寸就可以了,比如我们换成图片,只需要更改_makeGridItems
,将DraggableGridItem
的 child
的子组件更换为图片组件就搞定了。
List<DraggableGridItem> _makeGridItems(int count) {
var assetsName = [
'images/earth.jpeg',
'images/fire.png',
'images/girl.jpeg',
'images/island-coder.png',
'images/mb.jpeg'
];
return List.generate(
count,
(index) => DraggableGridItem(
isDraggable: true,
dragCallback: (_, isDragging) {
debugPrint('{$index}在拖拽:{$isDragging}');
},
child: Image.asset(
assetsName[index % assetsName.length],
fit: BoxFit.cover,
),
),
);
}
总结
本篇向大家推荐了一款简单实用的可拖拽 GridView
组件,基本上可以满足我们大部分支持拖拽的网格视图应用。大家如果有用过类似的组件,也欢迎在评论区推荐一下。
我是岛上码农,微信公众号同名。如有问题可以加本人微信交流,微信号:
island-coder
。👍🏻:觉得有收获请点个赞鼓励一下!
🌟:收藏文章,方便回看哦!
💬:评论交流,互相进步!