如何在 Flutter 中使 ReorderableListView 的 ListTile 在按钮/图标按下时可拖动?

22

我看到了ReorderableListView演示,发现他们有

"secondary: const Icon(Icons.drag_handle)"

但是查看reorderable_list.dart文件,发现整个列表在LongPressDraggable的情况下都可以被拖动[line 424]。所以我该如何明确地修改源代码或者自己的代码,才能将图标正式变为可拖动的手柄?

CheckboxListTile(
      key: Key(item.value),
      isThreeLine: true,
      value: item.checkState ?? false,
      onChanged: (bool newValue) {
        setState(() {
          item.checkState = newValue;
        });
      },
      title: Text('This item represents ${item.value}.'),
      subtitle: secondary,
      secondary: const Icon(Icons.drag_handle),  // Make this Icon drag source
    );

谢谢

3个回答

14

2021/05/29

作为答案的更新,ReorderableListView已经有了可自定义的处理程序:

由于最近对 ReorderableListView 进行了重构(PR:#74299和#74697),因此当在桌面上运行时,我们添加了自动拖动处理程序(使用buildDefaultDragHandles属性关闭)。如果这不是您想要的,则可以像以下方式将自己的拖动处理程序作为小部件添加到每个项目中:

ReorderableDragStartListener(
  index: index,
  child: const Icon(Icons.drag_handle),
),

你可以在这里查看详细信息:https://github.com/flutter/flutter/issues/46805

11

我认为Icon(Icons.drag_handle)只是为了外观而存在,要在ReorderableListView中拖动项目,您需要长按它。

您可以使用flutter_reorderable_list来实现这一点。正如您在其演示中所看到的,这个插件就是您想要的。

然而,它与ReorderableListView的工作方式有很大区别,可能需要进行一些代码更改。我创建了一个小部件以简化这个过程,该小部件在此处,它的演示在此处

看一下,如果符合您的用例,请使用它。


美丽。谢谢! - Johnny Boy

2

在移动平台上,默认情况下会隐藏DragHandles。但是,您可以在ReorderableListView中使用ReorderableDragStartListener为列表项添加拖动句柄。

 ListTile(
   key: Key('$index'),
   tileColor: _items[index].isOdd ? oddItemColor : evenItemColor,
   title: Text('Item ${_items[index]}'),
   trailing: ReorderableDragStartListener(
      key: ValueKey<int>(_items[index]),
      index: index,
      child: const Icon(Icons.drag_handle),
   ),
),

输出

enter image description here

完整的代码示例

import 'dart:ui';

import 'package:flutter/material.dart';

void main() => runApp(const ReorderableApp());

class ReorderableApp extends StatelessWidget {
  const ReorderableApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('ReorderableListView Sample')),
        body: const ReorderableExample(),
      ),
    );
  }
}

class ReorderableExample extends StatefulWidget {
  const ReorderableExample({super.key});

  @override
  State<ReorderableExample> createState() => _ReorderableExampleState();
}

class _ReorderableExampleState extends State<ReorderableExample> {
  final List<int> _items = List<int>.generate(50, (int index) => index);

  @override
  Widget build(BuildContext context) {
    final ColorScheme colorScheme = Theme.of(context).colorScheme;
    final Color oddItemColor = colorScheme.secondary.withOpacity(0.05);
    final Color evenItemColor = colorScheme.secondary.withOpacity(0.15);
    final Color draggableItemColor = colorScheme.secondary;

    Widget proxyDecorator(
        Widget child, int index, Animation<double> animation) {
      return AnimatedBuilder(
        animation: animation,
        builder: (BuildContext context, Widget? child) {
          final double animValue = Curves.easeInOut.transform(animation.value);
          final double elevation = lerpDouble(0, 6, animValue)!;
          return Material(
            elevation: elevation,
            color: draggableItemColor,
            shadowColor: draggableItemColor,
            child: child,
          );
        },
        child: child,
      );
    }

    return ReorderableListView(
      padding: const EdgeInsets.symmetric(horizontal: 40),
      children: <Widget>[
        for (int index = 0; index < _items.length; index += 1)
          ListTile(
            key: Key('$index'),
            tileColor: _items[index].isOdd ? oddItemColor : evenItemColor,
            title: Text('Item ${_items[index]}'),
            trailing: ReorderableDragStartListener(
              key: ValueKey<int>(_items[index]),
              index: index,
              child: const Icon(Icons.drag_handle),
            ),
          ),
      ],
      onReorder: (int oldIndex, int newIndex) {
        setState(() {
          if (oldIndex < newIndex) {
            newIndex -= 1;
          }
          final int item = _items.removeAt(oldIndex);
          _items.insert(newIndex, item);
        });
      },
    );
  }
}

原始帖子在这里: https://github.com/flutter/flutter/issues/25065#issuecomment-1381324936


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接