嵌套可重排序列表?

时间:2019-06-23 17:31:26

标签: flutter flutter-layout

我有一个由ReorderableListListTiles组成的ExpansionTiles,并且希望ExpansionTiles的子级可以重新排序。子代是递归的,因为它们也是ListTilesExpansionTiles的混合。这是我当前的代码:

Widget _buildList() {
  return Scrollbar(
    child: ReorderableListView(
      padding: const EdgeInsets.all(25),
      children: topLevelOrder.map<Widget>(_buildItem).toList(),
      onReorder: (oldIndex, newIndex) {
      // ...
      },
    ),
  );
}

Widget _buildItem(String id) {
  Map item = data[id];
  List children = item["children"];
  if (children.length > 0) {
    List<Widget> childWidgets = [];
    for (var child in children)
      childWidgets.add(_buildItem(child));
    return ExpansionTile(
      key: Key(id),
      initiallyExpanded: true,
      title: Text(id),
      children: [
        ReorderableListView(
          children: childWidgets,
          onReorder: (oldIndex, newIndex) {
            // ...
          },
        )
      ],
    );
  }
  return ListTile(
    key: Key(id),
    title: Text(id)
  );
}

其中data是测试数据的硬编码字典(仅两层)。但是,这会引发BoxConstraints forces an infinite height错误。如何解决此问题,否则如何实现嵌套的可重排序列表?

1 个答案:

答案 0 :(得分:0)

我尝试过类似的事情,但我只是不认为它以这种方式工作(也许它有效,我不确定),相反,我提供了多个 ReorderableListView(也可以 ReorderableListView.builder)小部件的解决方案嵌套在 SingleChildScrollView 小部件中,也可以嵌套在其他小部件中,正如您从示例中看到的那样。在我看来,这也适用于 op 问题

玩得开心飘飘

import 'package:flutter/material.dart';

/// This is the main application widget.

/// This is the stateful widget that the main application instantiates.
class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({Key? key}) : super(key: key);

  @override
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

/// This is the private State class that goes with MyStatefulWidget.
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  final List<int> _items = List<int>.generate(10, (int index) => index);
  final List<int> _items2 = List<int>.generate(15, (int index2) => index2);

  @override
  Widget build(BuildContext context) {
    final ColorScheme colorScheme = Theme.of(context).colorScheme;
    final Color oddItemColor = colorScheme.primary.withOpacity(0.05);
    final Color evenItemColor = colorScheme.primary.withOpacity(0.15);
    int index = 0;
    int index2 = 0;

    return Scaffold(
      appBar: AppBar(
        title: Text('Example'),
      ),
      body: SingleChildScrollView(
        child: Column(
          children: <Widget>[
            ListTile(title: Text('test 1')),
            ListTile(title: Text('test 2')),
            ReorderableListView(
              physics: ClampingScrollPhysics(),
              shrinkWrap: true,
              padding: const EdgeInsets.symmetric(horizontal: 40),
              children: <Widget>[
                for (index = 0; index < _items.length; index++)
                  ListTile(
                    key: Key('$index'),
                    tileColor:
                        _items[index].isOdd ? oddItemColor : evenItemColor,
                    title: Text('Item ${_items[index]}'),
                  ),
              ],
              onReorder: (int oldIndex, int newIndex) {
                setState(() {
                  if (oldIndex < newIndex) {
                    newIndex -= 1;
                  }
                  final int item = _items.removeAt(oldIndex);
                  _items.insert(newIndex, item);
                });
              },
            ),
            ListTile(title: Text('test 3')),
            ListTile(title: Text('test 4')),
            ReorderableListView(
              physics: ClampingScrollPhysics(),
              shrinkWrap: true,
              padding: const EdgeInsets.symmetric(horizontal: 40),
              children: <Widget>[
                for (index2 = 0; index2 < _items2.length; index2++)
                  ListTile(
                    key: Key('$index2'),
                    tileColor:
                        _items2[index2].isOdd ? oddItemColor : evenItemColor,
                    title: Text('Item ${_items2[index2]}'),
                  ),
              ],
              onReorder: (int oldIndex2, int newIndex2) {
                setState(() {
                  if (oldIndex2 < newIndex2) {
                    newIndex2 -= 1;
                  }
                  final int item = _items2.removeAt(oldIndex2);
                  _items2.insert(newIndex2, item);
                });
              },
            ),
            ListTile(title: Text('test 5')),
            ListTile(title: Text('test 6')),
          ],
        ),
      ),
    );
  }
}