一統天下 flutter - widget 列表類: ReorderableListView - 可拖拽排序的列表

源碼 https://github.com/webabcd/flutter_demo
作者 webabcd

一統天下 flutter - widget 列表類: ReorderableListView - 可拖拽排序的列表

示例如下:

lib\widget\list\reorderable_list_view.dart

/*
 * ReorderableListView - 可拖拽排序的列表
 */

import 'package:flutter/material.dart';

import '../../helper.dart';

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

  @override
  _ReorderableListViewDemoState createState() => _ReorderableListViewDemoState();
}

class _ReorderableListViewDemoState extends State<ReorderableListViewDemo> {

  List<String> _dataList = [];

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

    _dataList = ['content1', 'content2', 'content3', 'content4', 'content5'];
  }

  Widget _getItem(String content) {
    return Container(
      /// 可拖拽的項必須要指定 key
      key: ValueKey(content),
      alignment: Alignment.center,
      margin: const EdgeInsets.all(2),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(10),
        color: Colors.blue,
      ),
      child: MyTextSmall(content),
    );
  }

  void _onReorder(int oldIndex, int newIndex) {
    log('onReorder, oldIndex:$oldIndex, newIndex:$newIndex');
    setState(() {
      /// 按照拖拽排序的結果重新排序數據源,並重新渲染
      var item = _dataList.removeAt(oldIndex);
      if (newIndex > oldIndex) {
        _dataList.insert(newIndex - 1, item);
      } else {
        _dataList.insert(newIndex, item);
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("title"),),
      backgroundColor: Colors.orange,
      body: Column(
        children: [
          Expanded(
            child: ReorderableListView(
              /// 滾動方向 vertical 或 horizontal
              scrollDirection: Axis.vertical,
              /// header
              header: const MyText("header"),
              /// footer
              footer: const MyText("footer"),
              /// 內邊距
              padding: EdgeInsets.zero,
              /// 是否反向排列
              reverse: false,
              /// 指定 ReorderableListView 關聯的 ScrollController
              scrollController: null,
              /// 滾動到邊緣時的物理效果,參見 /lib/widget/scroll/single_child_scroll_view.dart
              physics: const BouncingScrollPhysics(),
              /// 留白區域佔可視區的百分比(0.0 - 1.0 之間)
              anchor: 0.0,
              /// 用於定義每個元素在滾動方向上的尺寸
              /// 也可以不指定這個,那麼就由每個元素自己決定尺寸(注:建議使用 itemExtent 指定尺寸,這樣性能會好一些)
              itemExtent: 40,

              /// 構造 ReorderableListView 中的每一項
              children: _dataList.map((e) => _getItem(e)).toList(),

              /// 拖拽排序操作完成後
              onReorder: _onReorder,
              /// 拖拽開始
              onReorderStart: (index) {
                log("onReorderStart:$index");
              },
              /// 拖拽結束
              onReorderEnd: (index) {
                log("onReorderEnd:$index");
              },
            ),
          ),

          /// 本例用於演示如何自定義拖拽行爲,以及如何自定義拖拽中的項的樣式
          /// 默認 android/ios 長按項後可拖拽,本例可以實現 android/ios 點擊項後可拖拽
          Expanded(
            child: ReorderableListView(
              itemExtent: 40,
              onReorder: _onReorder,

              /// 禁用默認的拖拽行爲
              buildDefaultDragHandles: false,
              /// 構造 ReorderableListView 中的每一項,並自定義其拖拽行爲
              children: [
                for (int index = 0; index < _dataList.length; index++)
                  /// ReorderableDelayedDragStartListener - 長按項後即可拖拽
                  /// ReorderableDragStartListener - 點擊項後即可拖拽
                  ReorderableDragStartListener (
                    key: ValueKey(_dataList[index]),
                    index: index,
                    child: Container(
                      alignment: Alignment.center,
                      margin: const EdgeInsets.all(2),
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(10),
                        color: Colors.blue,
                      ),
                      child: MyTextSmall(_dataList[index]),
                    ),
                  ),
              ],

              /// 用於定義拖拽中的項的樣式
              ///   child - 拖拽中的項
              ///   index - 拖拽中的項的索引位置
              proxyDecorator: (Widget child, int index, Animation<double> animation) {
                return Material(
                  child: Container(
                    decoration: const BoxDecoration(
                      color: Colors.red,
                    ),
                    child: Padding(
                      padding: const EdgeInsets.all(5),
                      child: child,
                    ),
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

源碼 https://github.com/webabcd/flutter_demo
作者 webabcd

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章