Bottom overflow due to bottom navigation bar and tab Bar
Asked Answered
C

3

4
@override
  Widget build(BuildContext context) {
    super.build(context);

    SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values);
    return AnnotatedRegion<SystemUiOverlayStyle>(
      value: SystemUiOverlayStyle(
        statusBarColor: Colors.transparent,
      ),
      child: Scaffold(
     key: _scaffoldKeyProfilePage,

      body: DefaultTabController(
        length: 2,
 child:RefreshIndicator(
          onRefresh: _onRefresh,
        child: NestedScrollView(
          
            headerSliverBuilder: (context, _) {
              return [
                SliverList(
                delegate: SliverChildListDelegate(
                 [                 BuildMainProfile(
              ....//
                 ),
                 Padding(
                ...//another design 
                 ), 
                
              ];
            },
            // You tab view goes here
            body: Column(
              children: <Widget>[
                TabBar(
              tabs: [
                Tab(text: 'A'),
                Tab(text: 'B'),
              ],
                ),
                Expanded(
              child: TabBarView(
                children: [
                  BuildPost(,

                  ),
                 BuildWings()
                ],
              ),
                ),
              ],
            ),
          ),),
      ),

}enter image description here


Above is the example of error which I am getting
error:A RenderFlex overflowed by 48 pixels on the bottom.
How to solve this issue? Tried using expanded on TabBar and giving flex of 1 to tab bar and flex of 10 to tabView , but with that tab bar shrinks on scrolling down.


Here below is the code for tabBar view A and B is even similar

class BuildPost extends StatefulWidget {
  final String uid;

  const BuildPost({
    Key key,
    @required this.uid,
  }) : super(key: key);
  @override
  _BuildPostState createState() => _BuildPostState();
}

class _BuildPostState extends State<BuildPost> {
  List<Post> _post = [];

  getUsersPost() async {
    final database = FirestoreDatabase();
    List<Post> _postModel = await database.getUsersPost(widget.uid);
    setState(() {
      _post = _postModel.toList();
    });
  }

  @override
  void initState() {
    getUsersPost();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return _post.isEmpty
        ? Container(
            height: 500,
            width: double.infinity,
          )
        : GestureDetector(
            child: Directionality(
                textDirection: TextDirection.ltr,
                child: AnimationLimiter(
                  child: StaggeredGridView.countBuilder(
                    padding: EdgeInsets.all(10),
                    shrinkWrap: true,
                    physics: NeverScrollableScrollPhysics(),
                    crossAxisCount: 3,
                    itemCount: _post.length,
                    itemBuilder: (context, index) {
                      return AnimationConfiguration.staggeredGrid(
                        position: index,
                        duration: const Duration(milliseconds: 500),
                        columnCount: 3,
                        child: SlideAnimation(
                          verticalOffset: 50.0,
                          child: FadeInAnimation(
                              duration: Duration(milliseconds: 1000),
                              child: BuildData(
                                totalPost: _post.length,
                                postList: _post,
                                index: index,
                                post: _post[index],
                              )),
                        ),
                      );
                    },
                    staggeredTileBuilder: (index) => StaggeredTile.count(
                        index % 7 == 0 ? 2 : 1,
                        index % 7 == 0 ? (2.1) : (1.05)),
                    mainAxisSpacing: 4.0,
                    crossAxisSpacing: 4.0,
                  ),
                )),
          );
  }
}

Cycloplegia answered 23/12, 2020 at 19:16 Comment(10)
I have managed to re-create the same UI without issue, could you please give more code for the Tabs so I can test more.Licht
@JacksonLee I have added the code for the TabsCycloplegia
I think your headerSliverBuilder is too tall, leaving to enough space for the TabBar in the body.Gride
@Gride that space is deliberately tall, which is dynamic. Where the user can put their bio.Cycloplegia
I think the body is supposed to be some scrollable widget (ListView, CustomScrollView). Can you put the TabBar at the bottom of headerSliverBuilder?Gride
I can't add the tab bar at the bottom of headerSliverBuilder, because when we scroll tab bar would be hidden and wouldn't stick to the top. Any other way out? My layout is almost similar to https://mcmap.net/q/629266/-instagram-profile-header-layout-in-flutterCycloplegia
Thanks, I just need the model for Post and BuildData widget - If its easier, drop the files into my onedrive - 1drv.ms/u/s!AoUkF50a_XNzgX0ocwbBGiaqELFQ?e=n1j4BkLicht
BuildData just contain the code for the grid ,which is nothing more than a rounded container with further gesture detector property. And Post is just a model class for the usersPost from Firestore.Cycloplegia
why is the Expanded is needed as the parent of the TabBarView? what does removing does?Upholster
Removing Expanded gives an errorCycloplegia
H
2

It is because the body height of NestedScrollView is from 0 to MediaQuery.of(context).size.height, while your TabBar inside the column make it layout a minimal height of TabBar.

Move TabBar inside builder

Form the example of NestedScrollView, you can see the TabBar is inside headerSliverBuilder. You can simply move the TabBar inside it (wrap a SliverToBoxAdapteror SliverAppBar to make it sliver).

Then you can remove the Column and Expand Widget above the TabBarView

child: NestedScrollView(
  headerSliverBuilder: (context, _) {
    return [
      SliverList( 
       ...
      ),
      SliverAppBar(
        pinned: true,
        primary: false,  // no reserve space for status bar
        toolbarHeight: 0,  // title height = 0
        bottom: TabBar(
          tabs: [
            Tab(text: 'A'),
            Tab(text: 'B'),
          ],
        ),
      )
    ];
  }
  body: TabBarView(
    children: [
     ...
  

enter image description here

Hemocyte answered 29/12, 2020 at 8:51 Comment(11)
Hey the issue with the first solution is I want the tab bar to be pinned +the issue with your first code is similar to this drive.google.com/file/d/1qTJa37BRax4rQv7egdptynRk0lHRMz8q/view the issue is , if you clearly see when we scroll up after reaching the bottom of tabView, the grid of tab view remains inside the headerSliverBuilder. headerSliver starts showing its component before we reach the top of the grid of tab View. And the issue with 2nd solution is ,TabBar gets shrink and deshrink on scrollingCycloplegia
I update with a ListView with ConstrainedBox solution. Check it out if it fit your situation.Hemocyte
Nope, it doesn't fit in, Now the issue is due to list view, the Grid scroll in its own position, and seems like there's no use of using NestedScrollView. Demo is here drive.google.com/file/d/1OrwxdvXiLo49eUP8ulC_tjVT1gmXoSyC/…Cycloplegia
No, I haven't set any scroller inside my NestedScrollViewCycloplegia
I see. I change the first solution using SliverAppBar with pinned is true. Is the layout fit?Hemocyte
Due to this SliverAppBar, there's a lot of unwanted space due to leading and title and the issue of "When we scroll up after reaching the bottom of tabView, the grid of tab view remains inside the headerSliverBuilder. headerSliver starts showing its component before we reach the top of the grid of tab View" -remains still thereCycloplegia
I remove the unwanted answer and update with SliverAppBar part. You can actually remove unwanted space (please see the update). I am quite a little bit lost what you really want in result. Your original question is the overflowing issue, but no much describing what your layout should be.Hemocyte
Could you please provide the code for the grid of yours, because I am still facing the same issue here drive.google.com/file/d/1164KZyVIVgoC0UMDj1jG2-nyZykqNO9E/… . We could see we never get to see the 0th grid again on scrolling.Cycloplegia
ok, I got where the issue was, I was having My nestedScrollViews property floatHeaderSlivers: true,Cycloplegia
Isn't this just the same answer as I gave?Gride
spkersten I think u are right. I haven't notice after trying so many options, the final one is like yours... Let me give you a upvote for your foresight.Hemocyte
G
0

The body property of NestedScrollView gets a tight height constraint equal to the space left over by headerSliverBuilder (considering the scroll position). In your code, you've as body a Column widget with a fixed height (the TabBar) widget in there. So when the height constraint of body gets smaller than the TabBar height, it will overflow the Column.

So in body, there must be a widget that can shrink to zero height, most likely a scrollable (ListView, CustomScrollView). In your case, you can move the TabBar to the bottom of headerSliverBuilder, wrapping it with:

SliverPersistentHeader(
  pinned: true,
  delegate: SimpleHeaderDelegate(
    child: TabBar(...),
  ),
)

using:

class SimpleHeaderDelegate extends SliverPersistentHeaderDelegate {
  SimpleHeaderDelegate({@required this.child});

  final PreferredSizeWidget child;

  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) => child;

  @override
  double get maxExtent => child.preferredSize.height;

  @override
  double get minExtent => child.preferredSize.height;

  @override
  bool shouldRebuild(covariant SimpleHeaderDelegate oldDelegate) => oldDelegate.child != child;
}
Gride answered 26/12, 2020 at 13:45 Comment(6)
I can't add the tab bar at the bottom of headerSliverBuilder, because when we scroll tab bar would be hidden and wouldn't stick to the top.Cycloplegia
I tried this but it has affected the UI design and scrolling isn't proper now if you could please check it out drive.google.com/file/d/1qTJa37BRax4rQv7egdptynRk0lHRMz8q/…Cycloplegia
I don't see much wrong in that gif. Maybe you want to give child in SimpleHeaderDelegate a white background?Gride
the issue is , if you clearly see when we scroll up after reaching the bottom of tabView, the grid of tab view remains inside the headerSliverBuilder. headerSliver starts showing its component before we reach the top of the grid of tab View.Cycloplegia
@kanwarmanraj Perhaps because you have set physics: NeverScrollableScrollPhysics(), for that grid?Gride
Actually no, I have set physics: ScrollPhysics()Cycloplegia
L
0

See SingleChildScrollView class, Expanding content to fit the viewport:

https://api.flutter.dev/flutter/widgets/SingleChildScrollView-class.html

Legman answered 3/6, 2022 at 18:8 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Orchardist

© 2022 - 2024 — McMap. All rights reserved.