Home > Software design >  How can I use 2 reorderble rows ? - Exception: "ScrollController attached to multiple scroll vi
How can I use 2 reorderble rows ? - Exception: "ScrollController attached to multiple scroll vi

Time:08-08

Here's a simplified code example of my problem. You have to add "reorderables: ^0.5.0" to your pubspec.yaml to execute.

import 'package:flutter/material.dart';
import 'package:reorderables/reorderables.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Drag and Drop Lists',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: OrderableRow(),
    );
  }
  
  
}

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

  @override
  State<OrderableRow> createState() => _OrderableRowState();
}

class _OrderableRowState extends State<OrderableRow> {
  late List<Widget> _listOfWidgets;
  late List<Widget> _listOfWidgets2;

  @override
  void initState() {
    super.initState();
    _listOfWidgets = <Widget>[
      Container(color: Colors.blue, key: const ValueKey(1), child: const Text('blue')),
      Container(color: Colors.red, key: const ValueKey(2), child: const Text('red')),
      Container(color: Colors.green, key: const ValueKey(3), child: const Text('green')),
    ];
    _listOfWidgets2 = <Widget>[
      Container(color: Colors.blue, key: const ValueKey(-1), child: const Text('blue')),
      Container(color: Colors.red, key: const ValueKey(-2), child: const Text('red')),
      Container(color: Colors.green, key: const ValueKey(-3), child: const Text('green')),
    ];
  }


  @override
  Widget build(BuildContext context) {
    void _onReorder(int oldIndex, int newIndex){
      setState(() {
        Widget col = _listOfWidgets.removeAt(oldIndex);
        _listOfWidgets.insert(newIndex,col);
      });
    }
    void _onReorder2(int oldIndex, int newIndex){
      setState(() {
        Widget col = _listOfWidgets2.removeAt(oldIndex);
        _listOfWidgets2.insert(newIndex,col);
      });
    }
    return Column(
      children: [
        ReorderableRow(
          onReorder: _onReorder,
          children: _listOfWidgets,
        ),
        ReorderableRow(
          onReorder: _onReorder2,
          children: _listOfWidgets2,
        ),
      ],
    );
  }
}

If I remove the second ReorderableRow it works and it's possbile to reorder the elements. But with it, it's not possible to reorder the element of listOfWidgets. If I try to drag an element it just disappears. there's following exception:

══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
The following assertion was thrown while handling a gesture:
Assertion failed:
file:///name/development/flutter/packages/flutter/lib/src/widgets/scroll_controller.dart:108:12
_positions.length == 1
"ScrollController attached to multiple scroll views."

When the exception was thrown, this was the stack:
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 251:49  throw_
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 29:3    assertFailed
packages/flutter/src/widgets/scroll_controller.dart 108:33                    get position
packages/flutter/src/widgets/scroll_controller.dart 115:33                    get offset
packages/reorderables/src/widgets/reorderable_flex.dart 381:53                [_scrollTo]
packages/reorderables/src/widgets/reorderable_flex.dart 741:11                <fn>
packages/flutter/src/widgets/drag_target.dart 746:47                          didEnter
packages/flutter/src/widgets/drag_target.dart 902:22                          <fn>
dart-sdk/lib/collection/list.dart 161:15                                      firstWhere
packages/flutter/src/widgets/drag_target.dart 897:56                          updateDrag
packages/flutter/src/widgets/drag_target.dart 824:5                           new
packages/flutter/src/widgets/drag_target.dart 554:35                          [_startDrag]
packages/flutter/src/widgets/drag_target.dart 483:37                          <fn>
packages/flutter/src/gestures/multidrag.dart 295:53                           <fn>
packages/flutter/src/gestures/recognizer.dart 198:24                          invokeCallback
packages/flutter/src/gestures/multidrag.dart 295:14                           [_startDrag]
packages/flutter/src/gestures/multidrag.dart 285:48                           <fn>
packages/flutter/src/gestures/multidrag.dart 530:7                            [_delayPassed]
dart-sdk/lib/_internal/js_dev_runtime/private/isolate_helper.dart 48:19       internalCallback

Handler: "onStart"
Recognizer:
  DelayedMultiDragGestureRecognizer#02801
════════════════════════════════════════════════════════════════════════════════════════════════════
Another exception was thrown: Assertion failed: file:///name/development/flutter/packages/flutter/lib/src/widgets/scroll_controller.dart:108:12

Thanks for help!

CodePudding user response:

If ReorderableRow has an attribute controller of type ScrollController then create a variable of that type and assign it to the second ReorderableRow's controller. Example :

/*...*/
ScrollController _controller = ScrollController();
/*...*/
ReorderableRow(
  controller: _controller,
  onReorder: _onReorder2,
  children: _listOfWidgets2,
)
/*...*/
  • Related