BugsBuggy
BugsBuggy

Reputation: 159

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,
                ),
              ),
            )
        )
    );
  }
}

Upvotes: 1

Views: 916

Answers (3)

eamirho3ein
eamirho3ein

Reputation: 17940

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);
        },
      ),

Upvotes: 2

fazilSizzlers
fazilSizzlers

Reputation: 325

Add dynamic padding to the ReorderableListview as below


ReorderableListView.builder(
padding: EdgeInsets.only(bottom: kBottomNavigationBarHeight + 15.0), // 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);
              },
              ),

kBottomNavigationBarHeight

get the height of bottom navigation bar and add as padding..

Upvotes: 0

Ganesh Somani
Ganesh Somani

Reputation: 2360

Add a bottom edge inset. An inset would add padding inside the control without losing your transparent notch behaviour.

This can be done with something like -

ReorderableListView.builder(
  padding(EdgeInsets.only(bottom: 60.0)),
  ...
)

This is based on the documentation here though I think it is a weird parameter naming as padding suggests offet but documentation says this as inset. Hence I hope this works for you.

Upvotes: 0

Related Questions