Repository: flutter
Issue: ReorderableListView with DragTarget children
Labels: c: new feature,framework,f: material design,f: scrolling,has reproducible steps,P3,found in release: 3.3,found in release: 3.7,team-design,triaged-design

I'd like to be able to both reorder _and_ combine children via `ReorderableListView`.  I'm not sure if interaction is Material or not, but it seems like a natural and intuitive way for the user to combine list items to me.

From looking at [the source](https://github.com/flutter/flutter/blob/d408d302e2/packages/flutter/lib/src/material/reorderable_list.dart#L59), it seems like in order to do this I need to make my `ReorderableListView::children` `DragTarget` templated with type `Key` such that my own `onWillAccept` and `onAccept` methods fire.  The problem with this is that it subverts the list reordering such that I can only move list items to the end of the list (I'm assuming because of `ReorderableListView`'s internal reliance on `DragTarget`).

Here's an MRE. For the sake of completeness I've added some extra functionality for wrapping a given child in `Draggable` or `DragTarget` that helped me in figuring out what was going on:

```
import 'package:flutter/material.dart';

void main() {
  runApp(ReorderAndCombineApp());
}

class ReorderAndCombineApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ReorderAndCombine(),
    );
  }
}

class ReorderAndCombine extends StatefulWidget {
  ReorderAndCombine({Key key}) : super(key: key);

  @override
  _ReorderAndCombineState createState() => _ReorderAndCombineState();
}

class _ReorderAndCombineState extends State<ReorderAndCombine> {
  List<Widget> items = List<Widget>();

  @override
  void initState() {
    super.initState();
    for (int i = 0; i < 3; i++) {
      items.add(buildItem(i, wrapInDraggable: false, wrapInDragTarget: true));
    }
  }

  Widget buildItem(int value,
    {bool wrapInDraggable = false, bool wrapInDragTarget = false})
  {
    Widget item = Card(
      key: UniqueKey(),
      child: ListTile(
        title: Text(value.toString()),
      ),
    );

    if (wrapInDraggable) {
      item = LongPressDraggable<Key>(
        key: UniqueKey(),
        child: item,
        feedback: SizedBox(child: item, width: 100),
      );
    }

    if (wrapInDragTarget) {
      return DragTarget<Key>(
        key: UniqueKey(),
        onWillAccept: (data) {
          print('Accepting!');
          return true;
        },
        onAccept: (data) {
          print('Accepted!');
        },
        builder: (BuildContext context, List<Key> candidateData,
            List rejectedData) {
          return item;
        },
      );
    } else {
      return item;
    }
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: ReorderableListView(
          onReorder: (int oldIndex, int newIndex) {
            if (oldIndex < newIndex) {
              // removing the item at oldIndex will shorten the list by 1.
              newIndex -= 1;
            }
            final Widget item = items.removeAt(oldIndex);
            items.insert(newIndex, item);
          },
          children: items,
        ),
      ),
    );
  }
}
```

If the call to `buildItem` in `initState` sets `wrapInDraggable` and `wrapInDragTaget` to `false`, the following expected behavior occurs:

![reorder](https://user-images.githubusercontent.com/3186522/95025800-ae34b080-0649-11eb-93de-0d9a4b88f9b6.gif)

With both `wrapInDraggable` and `wrapInDragTarget` `true` the following behavior occurs.  Basically it seems like I've completely subverted the reorderable property, but the children are accepting drops:

![reorder_both_true](https://user-images.githubusercontent.com/3186522/95026580-80eb0100-064f-11eb-8466-fb360af52f67.gif)

With only `wrapInDragTarget` `true` I get the behavior mentioned above.  That is, my list children are accepting drops, but I can reorder only by dragging a child to the end:

![reorder_dragtarget](https://user-images.githubusercontent.com/3186522/95026582-85afb500-064f-11eb-92e3-501f673ee467.gif)

Assuming what I want isn't currently possible, I've read through https://github.com/flutter/flutter/issues/66080 and the associated [design doc](https://docs.google.com/document/d/1JzNtMQ-jnPnSHEBoi6IO0x2qMMylwhvRslEDcmqiwSs/edit#heading=h.pub7jnop54q0) but it didn't seem like this was specifically mentioned other than the latest suggestion of generalizing list children on the former.  I'm happy to comment on the doc and / or other tickets if this would be helpful.  I can also take a stab at a PR for this but I'm relatively new to Flutter so it'd be helpful if someone could point me to the relevant parts of the `ReorderableListView` source.

P.S. Thanks to the Dart + Flutter teams for making such an enjoyable language + app SDK.