skip to Main Content

I want to make a ReordableListView containing several ExpansionTile but it doesn’t work, the ExpansionTile doesn’t open.

If I put the parameter buildDefaultDragHandles: false the ExpansionTile opens but the gesture for reordering the list no longer works.

How can I join the reorder gesture with ExpansionTile without affecting each other?

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

  @override
  State<Test> createState() => _TestState();
}

class _TestState extends State<Test> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: SizedBox(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        child: ReorderableListView.builder(
          //buildDefaultDragHandles: false,
          itemBuilder: (context, index) {
            return ExpansionTile(
              key: GlobalKey(),
              title: Container(
                height: 70.0,
                color: Colors.blue,
              ),
              children: [
                Container(
                  height: 30.0,
                  color: Colors.green,
                ),
              ],
            );
          },
          itemCount: 10,
          onReorder: (oldIndex, newIndex) {},
        ),
      ),
    );
  }
}

2

Answers


  1. Having ExpansionTile leading and ReorderableListView handler at same place is kinda bad ux i think, you can have it like row or change one to the leading

    You can do

    itemBuilder: (context, index) {
      return ExpansionTile(
        leading: Icon(Icons.arrow_downward),
        controlAffinity: ListTileControlAffinity.leading,
        key: GlobalKey(),
        title: Container(
          height: 70.0,
          color: Colors.blue,
        ),
        children: [
          Container(
            height: 30.0,
            color: Colors.green,
          ),
        ],
      );
    },
    
    Login or Signup to reply.
  2. I’m wondering it would work if you wrap the container with a Dismissible widget so that you can swipe to remove the item

      itemBuilder: (context, index) {
      final item = items[index];
      return Dismissible(
        // Each Dismissible must contain a Key. Keys allow Flutter to
        // uniquely identify widgets.
        key: Key(item),
        // Provide a function that tells the app
        // what to do after an item has been swiped away.
        onDismissed: (direction) {
          // Remove the item from the data source.
          setState(() {
            items.removeAt(index);
          });
    
          // Then show a snackbar.
          ScaffoldMessenger.of(context)
              .showSnackBar(SnackBar(content: Text('$item dismissed')));
        },
        child: ListTile(
          title: Text(item),
        ),
      );
    },
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search