Listview 颤振可排序拖放列表视图

Listview 颤振可排序拖放列表视图,listview,drag-and-drop,flutter,flutter-animation,Listview,Drag And Drop,Flutter,Flutter Animation,因此,我开始学习颤振,并希望使用材料设计拖放列表,就像在材料指南网站上看到的一样 相比之下,我尝试过的所有库看起来都是垃圾。是否有一个我缺少的好的库,或者一个原生的Flutter小部件 检查。它正好做到了这一点。 它非常平滑,没有性能问题,能够处理数千个项目 然而,它的实现并不像通常的flatter小部件那样简单 如果您对此有困难,我建议您使用我创建的小部件,将flatter/ReorderableListViews导入knopp/ReorderableList 这个小部件非常容易使用,但是它

因此,我开始学习颤振,并希望使用材料设计拖放列表,就像在材料指南网站上看到的一样

相比之下,我尝试过的所有库看起来都是垃圾。是否有一个我缺少的好的库,或者一个原生的Flutter小部件

检查。它正好做到了这一点。 它非常平滑,没有性能问题,能够处理数千个项目

然而,它的实现并不像通常的flatter小部件那样简单

如果您对此有困难,我建议您使用我创建的小部件,将
flatter/ReorderableListView
s导入
knopp/ReorderableList

这个小部件非常容易使用,但是它没有提供同样的灵活性,而且由于它与
子项
列表
一起工作,它的可伸缩性不如原来的小部件

这是,这是。

我已经试过了,但没有一个工作正常-在拖动过程中出现了一些不需要的瑕疵。 因此,我尝试制定自己的解决方案:

ListView.builder(
  itemBuilder: (context, index) => buildRow(index),
  itemCount: trackList.length,
),

Widget buildRow(int index) {
  final track = trackList[index];
  ListTile tile = ListTile(
    title: Text('${track.getName()}'),
  );
  Draggable draggable = LongPressDraggable<Track>(
    data: track,
    axis: Axis.vertical,
    maxSimultaneousDrags: 1,
    child: tile,
    childWhenDragging: Opacity(
      opacity: 0.5,
      child: tile,
    ),
    feedback: Material(
      child: ConstrainedBox(
        constraints:
            BoxConstraints(maxWidth: MediaQuery.of(context).size.width),
        child: tile,
      ),
      elevation: 4.0,
    ),
  );

  return DragTarget<Track>(
    onWillAccept: (track) {
      return trackList.indexOf(track) != index;
    },
    onAccept: (track) {
      setState(() {
        int currentIndex = trackList.indexOf(track);
        trackList.remove(track);
        trackList.insert(currentIndex > index ? index : index - 1, track);
      });
    },
    builder: (BuildContext context, List<Track> candidateData,
        List<dynamic> rejectedData) {
      return Column(
        children: <Widget>[
          AnimatedSize(
            duration: Duration(milliseconds: 100),
            vsync: this,
            child: candidateData.isEmpty
                ? Container()
                : Opacity(
                    opacity: 0.0,
                    child: tile,
                  ),
          ),
          Card(
            child: candidateData.isEmpty ? draggable : tile,
          )
        ],
      );
    },
  );
}
ListView.builder(
itemBuilder:(上下文,索引)=>buildRow(索引),
itemCount:trackList.length,
),
小部件构建行(int索引){
最终曲目=曲目列表[索引];
ListTile=ListTile(
标题:文本(“${track.getName()}”),
);
可拖动可拖动=长按可拖动(
数据:跟踪,
轴:轴垂直,
最大同时阻力:1,
孩子:瓦片,
ChildWhenDraging:不透明度(
不透明度:0.5,
孩子:瓦片,
),
反馈:材料(
子:约束框(
限制条件:
BoxConstraints(maxWidth:MediaQuery.of(context).size.width),
孩子:瓦片,
),
标高:4.0,
),
);
返回DragTarget(
onWillAccept:(跟踪){
返回trackList.indexOf(track)!=索引;
},
onAccept:(轨道){
设置状态(){
int currentIndex=trackList.indexOf(track);
轨迹列表。删除(轨迹);
插入(当前索引>索引?索引:索引-1,轨道);
});
},
生成器:(BuildContext上下文,列出候选数据,
列表拒绝数据){
返回列(
儿童:[
动画大小(
持续时间:持续时间(毫秒:100),
vsync:这个,,
孩子:candidateData.isEmpty
?容器()
:不透明度(
不透明度:0.0,
孩子:瓦片,
),
),
卡片(
子项:candidateData.isEmpty?可拖动:平铺,
)
],
);
},
);
}
我想,这不是最好的解决方案,我想可能会进一步改变它,但现在它工作得很好。

颤振本身提供了一种(材料)。

您可以使用本机flatter小部件,
ReorderableListView
来实现它,下面是这样做的示例

List<String> _list = ["Apple", "Ball", "Cat", "Dog", "Elephant"];

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(),
    body: ReorderableListView(
      children: _list.map((item) => ListTile(key: Key("${item}"), title: Text("${item}"), trailing: Icon(Icons.menu),)).toList(),
      onReorder: (int start, int current) {
        // dragging from top to bottom
        if (start < current) {
          int end = current - 1;
          String startItem = _list[start];
          int i = 0;
          int local = start;
          do {
            _list[local] = _list[++local];
            i++;
          } while (i < end - start);
          _list[end] = startItem;
        }
        // dragging from bottom to top
        else if (start > current) {
          String startItem = _list[start];
          for (int i = start; i > current; i--) {
            _list[i] = _list[i - 1];
          }
          _list[current] = startItem;
        }
        setState(() {});
      },
    ),
  );
}
List _List=[“苹果”、“球”、“猫”、“狗”、“大象”];
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(),
正文:ReorderableListView(
子项:_list.map((item)=>ListTile(key:key(${item})、title:Text(${item})、trailing:Icon(Icons.menu))).toList(),
onReorder:(int开始,int当前){
//从上到下拖动
如果(启动<电流){
int end=电流-1;
字符串startItem=_list[start];
int i=0;
int local=开始;
做{
_列表[本地]=_列表[++本地];
i++;
}而(i当前){
字符串startItem=_list[start];
对于(int i=开始;i>当前;i--){
_列表[i]=_列表[i-1];
}
_列表[当前]=startItem;
}
setState((){});
},
),
);
}
颤振团队介绍了小部件

ReorderableListView(
儿童:[
for(appState.menuButtons中的变量项)
文本(“数据”)
],
)

您的版本运行良好,谢谢。我希望它是一个小滞后,虽然当重新排序每个瓷砖。不知道在发布版本中是否会更流畅。另外,我不知道如何在重新排序时自定义/消除振动。我还遇到了一个问题,即当我使列表平铺可拆分()时,句柄不会移动,而其余部分会像应该的那样滑开。我知道这不是一个解决方案,但在我的应用程序中,经过一些斗争后,我决定使用重新排序模式(因此,在重新排序模式下,我使用重新排序列表,并且有一个句柄(您不能做任何其他事情)如果您使用的是
ReorderingListSimple
,也许您可以使用
childrenAlreadyHaveListener=true
,然后手动将
reorderablestener
放入
listile
并使其在
Dismissible``s
onRezize`上消失!让我来知道它是否有效!!我知道这不太好,但也许这是有效的临时解决方案。看来我做了一些无用的工作。)总之,这是一次有趣的经历。很遗憾,'ReorderableListView'没有使用builder,但我想我会根据自己的需要使用它。Thanks@AndreyTurkovskyReorderableListView也有构建器长按以重新排序只是一个细节,据我所知,您应该避免空的setState调用,在我看来,onReorder中的所有代码都可能位于setState调用中?注意,长时间的重新订购绝对违反了材料设计规范,不应该在Android上使用(不知道iOS)。据我所知,到目前为止,没有办法提供可以通过
ReorderableListView
@DavidMulder简单抓取的手柄,这就是flift的实现方式
ReorderableListView(
      children: <Widget>[
        for (var item in appState.menuButtons) 
        Text('data')              

      ],
    )