하단 탐색 모음 및 탭 모음으로 인한 하단 오버플로

Dec 24 2020
@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()
                ],
              ),
                ),
              ],
            ),
          ),),
      ),

}


위는 내가 오류가 발생하는 오류의 예입니다
: RenderFlex가 하단에 48 픽셀로 넘쳤습니다.
이 문제를 해결하는 방법? TabBar에서 확장을 사용하고 탭 막대에 1의 플렉스를 제공하고 tabView에 10의 플렉스를 제공했지만 해당 탭 막대를 사용하면 아래로 스크롤하면 축소됩니다.


다음은 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 yellowgray Dec 29 2020 at 15:51

의 본문 높이는 NestedScrollView0에서 MediaQuery.of (context) .size.height까지이고 열 내부의 TabBar 는 레이아웃을 TabBar의 최소 높이로 만들기 때문입니다.

빌더 내에서 TabBar 이동

NestedScrollView 예제를 구성 하면 TabBar가 headerSliverBuilder 내부에 있음을 알 수 있습니다. TabBar를 내부 로 이동하기 만하면 됩니다 ( SliverToBoxAdapter또는 SliverAppBar얇게 만들기 위해).

그런 다음 TabBarView 위의 ColumnExpand위젯을 제거 할 수 있습니다.

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: [
     ...
  

1 spkersten Dec 26 2020 at 20:45

body속성은 (스크롤 위치를 고려하여) NestedScrollView남은 공간과 동일한 높이 제약 조건 을 가져 headerSliverBuilder옵니다. 코드에서 Column고정 높이 ( TabBar) 위젯이 있는 위젯을 본문 으로 사용했습니다. 몸의 높이 제한은보다 작은 얻을 때 그래서 TabBar높이, 그것은 오버 플로우됩니다 Column.

따라서 body에는 높이가 0으로 줄어들 수있는 위젯이 있어야합니다. 대부분 스크롤 가능 ( ListView, CustomScrollView)입니다. 귀하 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;
}