• 카테고리

    질문 & 답변
  • 세부 분야

    모바일 앱 개발

  • 해결 여부

    미해결

TabBar의 활용에 대한 질문입니다.

20.04.10 14:55 작성 조회수 489

0

강의 내용을 벗어나는 부분이라 문의를 드려도 되는지 고민했습니다.

개발에 입문하는 과정에 미숙하다보니, 홀로 해결하기가 어려워 이렇게 질문을 드려봅니다. 

저는 앱바와 별개로 Body 부분에서 탭바를 사용하고자 하고 있습니다. 

구조를 의사코드 형태로 설명하자면, 

return 스캐폴드(

  앱바: 앱바(

    타이틀(), 액션(),

  ),

  바디: 컨테이너(

    차일드: 싱글차일드스크롤뷰(

      컨테이너: 컨테이너(컬럼(

        탭바(),

        탭바뷰(),

      ),

))

이런 구조입니다. 

즉 앱바가 아닌 컨텐츠가 들어가는 바디 영역에서 위와 아래로 화면을 반분하여 위쪽의 컨테이너에는 게시물의 내용을 보여주고,

아래쪽에 탭바로 섹션을 나누어 그 아래 탭바뷰 영역에 각 섹션별의 화면을 보여주고 싶은 것이 의도입니다.

저는 탭바를 이용하면 이 부분에 문제가 없을 것이라 생각했으나, 실제 구현을 해보면 아래와 같은 에러가 발생하는 것을 확인하였습니다. 

이에 어떤 식으로 해결하거나 구현하면 좋을지 조언을 해주셨으면 하는 간절한 바람입니다. 

부디 부탁드립니다. 

════════ Exception caught by rendering library ═════════════════════════════════════════════════════

The following assertion was thrown during performResize():

Horizontal viewport was given unbounded height.

Viewports expand in the cross axis to fill their container and constrain their children to match their extent in the cross axis. In this case, a horizontal viewport was given an unlimited amount of vertical space in which to expand.

The relevant error-causing widget was: 

  TabBarView file:///C:/Users/gomeu/OneDrive/Workspace/AndroidStudioProjects/wintogether/lib/customer_detail_page.dart:106:15

When the exception was thrown, this was the stack: 

#0      RenderViewport.performResize.<anonymous closure> (package:flutter/src/rendering/viewport.dart:1221:15)

#1      RenderViewport.performResize (package:flutter/src/rendering/viewport.dart:1233:6)

#2      RenderObject.layout (package:flutter/src/rendering/object.dart:1703:9)

#3      RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)

#4      RenderObject.layout (package:flutter/src/rendering/object.dart:1724:7)

...

The following RenderObject was being processed when the exception was fired: RenderViewport#61004 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE

...  needs compositing

...  parentData: <none> (can use size)

...  constraints: BoxConstraints(0.0<=w<=411.4, 0.0<=h<=Infinity)

...  size: MISSING

...  axisDirection: right

...  crossAxisDirection: down

...  offset: _PagePosition#d97f6(offset: null, range: null..null, viewport: null, ScrollableState, PageScrollPhysics -> PageScrollPhysics -> ClampingScrollPhysics -> ClampingScrollPhysics, IdleScrollActivity#bbad0, ScrollDirection.idle)

...  anchor: 0.0

RenderObject: RenderViewport#61004 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE

  needs compositing

  parentData: <none> (can use size)

  constraints: BoxConstraints(0.0<=w<=411.4, 0.0<=h<=Infinity)

  size: MISSING

  axisDirection: right

  crossAxisDirection: down

  offset: _PagePosition#d97f6(offset: null, range: null..null, viewport: null, ScrollableState, PageScrollPhysics -> PageScrollPhysics -> ClampingScrollPhysics -> ClampingScrollPhysics, IdleScrollActivity#bbad0, ScrollDirection.idle)

  anchor: 0.0

...  center child: _RenderSliverFractionalPadding#37a2c NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE

...    parentData: paintOffset=Offset(0.0, 0.0)

...    constraints: MISSING

...    geometry: null

...    child: RenderSliverFillViewport#cb2ba NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE

...      parentData: paintOffset=Offset(0.0, 0.0)

...      constraints: MISSING

...      geometry: null

...      no children current live

════════════════════════════════════════════════════════════════════════════════════════════════════

════════ (2) Exception caught by rendering library ═════════════════════════════════════════════════

RenderBox was not laid out: RenderViewport#61004 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE

'package:flutter/src/rendering/box.dart':

Failed assertion: line 1687 pos 12: 'hasSize'

The relevant error-causing widget was: 

  TabBarView file:///C:/Users/gomeu/OneDrive/Workspace/AndroidStudioProjects/wintogether/lib/customer_detail_page.dart:106:15

════════════════════════════════════════════════════════════════════════════════════════════════════

코드는 아래와 같습니다. 

import 'package:flutter/material.dart';

import 'tab_page.dart';

class CustomerDetailPage extends StatefulWidget {
  const CustomerDetailPage({ Key key }) : super(key: key);

  @override
  _CustomerDetailPageState createState() => _CustomerDetailPageState();
}

class _CustomerDetailPageState extends State<CustomerDetailPage> with SingleTickerProviderStateMixin {
  final List<Tab> customerTabs = <Tab>[
    Tab(text: 'DETAIL'),
    Tab(text: 'DEAL'),
    Tab(text: 'ACTIVITY'),
    Tab(text: 'NOTE'),
    Tab(text: 'LOG'),
  ];

  TabController _tabController;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(vsync: this, length: customerTabs.length);
  }

  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.white,
        elevation: 0,
        actions: <Widget>[
          IconButton(
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => TabPage())
              );
            },
            icon: Icon(Icons.arrow_back, color: Colors.black),
          ),
          IconButton(
            onPressed: () => {},
            icon: Icon(Icons.edit, color: Colors.black),
          ),
        ],
      ),
      body: Container(
        color: Colors.white,
        alignment: Alignment.topCenter,
        child: SingleChildScrollView(
          child: Column(
            children: <Widget>[
              Container(
                child:
                  Column(
                    children: <Widget>[
                      Padding(
                        padding: EdgeInsets.only(top: 20.0),
                        child:
                        Stack(
                          children: <Widget>[
                            SizedBox(
                                width: 140.0,
                                height: 140.0,
                                child: CircleAvatar(
                                  backgroundImage: NetworkImage(
                                      'https://www.atlassian.com/dam/jcr:ba03a215-2f45-40f5-8540-b2015223c918/Max-R_Headshot%20(1).jpg'
                                  ),
                                )
                            )
                          ],
                        ),
                      ),
                      Padding(
                        padding: EdgeInsets.only(top: 20.0),
                        child: Text('Max Carson', style: TextStyle(fontSize: 22)),
                      ),
                      Padding(
                        padding: EdgeInsets.only(top: 0.0),
                        child: Text('UI/UX Designer, Microsoft', style: TextStyle(fontSize: 18, color: Colors.grey)),
                      ),
                      Padding(
                        padding: EdgeInsets.only(top: 30.0),
                      ),
                    ],
                  )
              ),
              Container(
                child:
                  TabBar(
                    labelColor: Colors.black,
                    controller: _tabController,
                    tabs: customerTabs,
                  ),
              ),
              TabBarView(
                controller: _tabController,
                children: <Widget>[
                  Text(''),
                  Text(''),
                  Text(''),
                  Text(''),
                  Text(''),
                ],
              ),
            ],
          ),
        ),
      )
    );
  }
}

답변 2

·

답변을 작성해보세요.

1

에러 내용으로는 높이 정보를 가져야하는 위젯이 있는데 높이를 모르는 것 같습니다.

의문은 body 영역을 위 아래 반으로 나눠서 표시한다고 하셨는데 SingleChildScrollView로 감싸져 있습니다. 이 부분이 논리적으로 이해가 잘 되지 않는 부분이고요.

이게 잘 동작하려면 위 아래 부분이 모두 높이를 알아야 할 것 같습니다. 확인 방법은 SizedBox로 감싸서 강제로 height 값을 적당히 줘 보는 방법입니다.

제 생각에는 SingleChildScrollView를 걷어내고 잘 되는지 보시고 Tab 사용방법 레퍼런스(https://flutter.dev/docs/cookbook/design/tabs)와 좀 다르게 한 것이라 저도 말씀하신 구조대로 동작이 될지는 확신이 되지 않네요. 

만약 안 되면 Tab, TabBarView를 사용하지 마시고 별도로 구현해야 할 수도 있습니다.

해 보시고 결과 알려주세요.

0

정은성님의 프로필

정은성

질문자

2020.04.13

SingleChildScrollView의 충돌이 문제였던 것 같습니다. 해당 부분을 ListView로 바꾸고 각 리스트의 엔트리를 정보 컨테이너, 탭바의 컨테이너, 탭바 뷰의 컨테이너로 변경함으로서 문제가 해결되었습니다. 

도움에 정말 감사드립니다.