由于底部导航栏和标签栏导致底部溢出

时间:2020-12-23 19:16:36

标签: flutter dart flutter-layout flutter-sliver flutter-listview

@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


以上是我得到的错误示例
错误:RenderFlex 在底部溢出了 48 个像素。
如何解决这个问题?尝试在 TabBar 上使用扩展并将 1 的 flex 赋予标签栏并将 10 的 flex 赋予 tabView ,但该标签栏会在向下滚动时缩小。


下面是 tabBar 视图的代码 A 和 B 甚至相似

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

2 个答案:

答案 0 :(得分:1)

这是因为 NestedScrollView 的 body 高度是从 0 到 MediaQuery.of(context).size.height,而你在列内的 TabBar 使它布局的最小高度为标签栏。

在构建器中移动 TabBar

NestedScrollView为例,可以看到TabBar在headerSliv​​erBuilder里面。您只需将 TabBar 移动到其中(包裹一个 SliverToBoxAdapterSliverAppBar 以使其变细)。

然后您可以删除 TabBarView

上方的 ColumnExpand Widget
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

答案 1 :(得分:0)

bodyNestedScrollView 属性得到严格的高度约束,等于 headerSliverBuilder 留下的空间(考虑滚动位置)。在您的代码中,您将一个 Column 小部件作为主体,其中具有固定高度(TabBar)小部件。所以当 body 的高度约束小于 TabBar 高度时,它会溢出 Column

所以在body中,必须有一个可以缩小到零高度的小部件,很可能是一个可滚动的(ListViewCustomScrollView)。在您的情况下,您可以将 TabBar 移动到 headerSliverBuilder 的底部,将其包装为:

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

使用:

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