Search code examples
flutterdartflutter-layout

Last element is hidden behind BottomAppBar with ReorderableListView


I'm using a ReorderableListView builder in combination with a Bottom App Bar with a FAB. I set extendBody because I want the FAB notch to be transparent when scrolling up/down the list. However with a ReorderableListView I cannot scroll down to the last list item because the list item is hidden behind the Bottom App Bar.

Here's a demonstration:

enter image description here

This is not the case with a regular ListView as you can see in the code example below and on this picture right here. This would be my intended behaviour because the last list item is fully visible:

enter image description here

Important: It's not a solution to just set extendBody to false because there would be no transparent notch when scrolling. The scrolling behaviour itself is correct for ReorderableListView and ListView and looks like this when scrolling:

enter image description here

Is there a way to access the last list element with a Reorderable List View similar than with a List View?

Here's a code example with both versions:

import 'package:flutter/material.dart';

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

class SO extends StatelessWidget {
  List<String> myList = ["a", "b", "c", "d", "e", "f", "g", "h"];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Builder(
            builder: (context) => Scaffold(
              extendBody: true,
              appBar: AppBar(),
              body:
              // CANNOT scroll up to the last element
              ReorderableListView.builder(
                  itemCount: myList.length,
                  itemBuilder: (BuildContext context, int index) {
                    return Container(
                      key: ValueKey(myList[index]),
                      height: 150,
                      color: Colors.green,
                      child: Center(child: Text('Entry ${myList[index]}')),
                    );
                  },
                onReorder: (oldIndex, newIndex){
                  if (newIndex > oldIndex) newIndex --;
                  final item = myList.removeAt(oldIndex);
                  myList.insert(newIndex, item);
              },
              ),

              /*
              // CAN scroll up to the last element
              ListView.builder(itemCount: myList.length,
                itemBuilder: (BuildContext context, int index) {
                  return Container(
                    key: ValueKey(myList[index]),
                    height: 150,
                    color: Colors.green,
                    child: Center(child: Text('Entry ${myList[index]}')),
                  );
                },
              ),
              */
              floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
              floatingActionButton: FloatingActionButton(
                onPressed: () {},
              ),
              bottomNavigationBar: BottomAppBar(
                shape: const CircularNotchedRectangle(),
                notchMargin: 18,
                color: Colors.blue,
                child: Container(
                  height: 60,
                ),
              ),
            )
        )
    );
  }
}

Solution

  • You can add padding like this:

    ReorderableListView.builder(
            padding: EdgeInsets.only(bottom: kBottomNavigationBarHeight + 16),//<--- add this
            itemCount: myList.length,
            itemBuilder: (BuildContext context, int index) {
              return Container(
                key: ValueKey(myList[index]),
                height: 150,
                color: Colors.green,
                child: Center(child: Text('Entry ${myList[index]}')),
              );
            },
            onReorder: (oldIndex, newIndex) {
              if (newIndex > oldIndex) newIndex--;
              final item = myList.removeAt(oldIndex);
              myList.insert(newIndex, item);
            },
          ),