首页 > 其他分享 >flutter 效果实现 —— 可拖拽 GridView

flutter 效果实现 —— 可拖拽 GridView

时间:2022-09-05 22:45:15浏览次数:65  
标签:index GridView myData 拖拽 dataList child print data flutter

效果:

代码:

class GridDragView extends StatefulWidget {
  const GridDragView({Key? key}) : super(key: key);

  @override
  State<GridDragView> createState() => _GridDragViewState();
}

const List<String> alphas = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L'];

class _GridDragViewState extends State<GridDragView> {
  List<String> dataList = List.generate(11, (index) => alphas[index]);

  late List<String> backupDataList;

  bool showSrcElement = false;

  int overlapIndex = -1;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GridView.builder(
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 3,
        ),
        itemCount: dataList.length,
        itemBuilder: (context, index) => _buildItem(index, dataList[index]),
      ),
    );
  }

  Widget _buildItem(index, myData) {
    return Draggable<String>(
      data: myData,
      child: DragTarget<String>(
        builder: (context, candidateData, rejectedData) {
          var myIndex = dataList.indexOf(myData);
          return myIndex == overlapIndex
              ? SizedBox.shrink()
              : Card(
                  child: Center(
                    child: Text("x = $myData"),
                  ),
                );
        },
        //松手时如果onWillAccept返回true时触发调用
        onAccept: (data) {
          // setState(() {
          //   overlapIndex = -1;
          // });
        },
        //手指拖着一个widget从另一个widget头上滑走时触发调用
        onLeave: (data) {
          print('$data is Leaving item $myData');
          setState(() {
            overlapIndex = -1;
            showSrcElement = false;
            dataList = [...backupDataList];
          });
        },
        //移动到目标组件时触发调用
        //返回值是接下来松手 是否需要将数据给这个widget?
        onWillAccept: (data) {
          print('index: $index');
          print('$myData will accept item $data');
          if (data != null && data != myData) {
            //目标位置留空
            //原位置移除(由前后位置自动占位)
            setState(() {
              var draggingIndex = backupDataList.indexOf(data);
              var myIndex = backupDataList.indexOf(myData);
              print('draggingIndex: $draggingIndex');
              print('myIndex: $myIndex');
              dataList.removeAt(draggingIndex);
              dataList.insert(index, data);
              showSrcElement = true;
              overlapIndex = index;
            });
          }
          return true;
        },
      ),
      //拖动事件
      onDragStarted: () {
        //开始拖动,备份数据源
        print('item $myData ---------------------------onDragStarted');
        backupDataList = [...dataList];
      },
      onDraggableCanceled: (Velocity velocity, Offset offset) {
        print(
            'item $myData ---------------------------onDraggableCanceled,velocity = $velocity,offset = $offset');
        //拖动取消,还原数据源
        setState(() {
          overlapIndex = -1;
          showSrcElement = false;
          dataList = [...backupDataList];
        });
      },
      onDragCompleted: () {
        //拖动完成,刷新状态
        print("item $myData ---------------------------onDragCompleted");
        setState(() {
          showSrcElement = false;
          overlapIndex = -1;
        });
      },
      //拖动时的组件
      feedback: Card(
        child: Padding(
          padding: EdgeInsets.symmetric(horizontal: 50.0, vertical: 50.0),
          child: Center(
            child: Text("x = $myData"),
          ),
        ),
      ),
      //被拖动的组件的最初位置
      childWhenDragging: showSrcElement
          ? Card(
              child: Padding(
                padding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 50.0),
                child: Center(
                  child: Text("x = $myData"),
                ),
              ),
            )
          : SizedBox.shrink(),
    );
  }
}

标签:index,GridView,myData,拖拽,dataList,child,print,data,flutter
From: https://www.cnblogs.com/lemos/p/16659892.html

相关文章

  • Flutter 3.+更新记录
    Flutter3.3稳定版出来了,于是决定把之前Flutter工程的代码更新下其中里面有些涉及到组件的弃用在此记录ElevatedButton代替了RaisedButton为带阴影的悬浮按钮BottomN......
  • 前端拖拽的简单实现
    鼠标按下拖动松开时鼠标的位置分析:  <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><metahttp-equiv="X-UA-Compatible"content=......
  • 直播app开发搭建,存放多张图片的GridView,并可以点击放大
    直播app开发搭建,存放多张图片的GridView,并可以点击放大View <ScrollView    android:id="@+id/scorll"    android:layout_width="match_parent"  ......
  • JS实现拖拽效果
    HTML部分<divid="container"><divid="drag">拖拽区域</div></div> CSS部分:#container{width:300px;/*overflow:hidden有......
  • Flet-基于Flutter的Python跨平台开发框架
    什么是FletFlet是一个框架,允许用你喜欢的语言构建交互式多用户Web,桌面和移动应用程序,而无需拥有前端开发的经验。主要特点在几分钟内从想法到应用程序为您的团队,周末项......
  • 每个 Flutter 开发者都需要知道的小部件
    每个Flutter开发者都需要知道的小部件在我之前的文章中,我谈到了使用dart编程语言进行Flutter的面向对象编程。(这里是给没看过的人的链接:Dart编程语言基础。什么......
  • vb.net DataGridViewCheckBoxColumn 自绘显示
     自定义自绘DataGridView扩展中发现CheckBox等控件显示错误,摸索了半天,总结一下片段:Case"DataGridViewCheckBoxCell"  NCell=NewDataGridViewCheckBoxC......
  • vue+elementUI+sortablejs --- el-table列表拖拽
    前言:最近很多需求都与拖拽有关,一般拖拽用的都是 vuedraggable 但是要是在el-table列表里面拖拽当用vuedraggable去包裹table列表包外层只能拖动整个列表包里面数......
  • qt 文件拖拽
    将某类型文件拖拽到qt窗口并执行相应动作。这里以播放某些文件为例。类继承自QWidget,重写函数:1voiddragEnterEvent(QDragEnterEvent*event)override;2vo......
  • flutter系列之:构建Widget的上下文环境BuildContext详解
    目录简介BuildContext的本质BuildContext和InheritedWidgetBuildContext的层级关系总结简介我们知道Flutter中有两种Widget,分别是StatelessWidget和StatefulWidget,Statel......