【问题标题】:Sliver with TabBarView & SliverFillRemaining gives Bottom Overflowed by xxx pixels带有 TabBarView 和 SliverFillRemaining 的 Sliver 给出了 xxx 像素的底部溢出
【发布时间】:2021-01-12 17:09:53
【问题描述】:

需要有关溢出像素问题的帮助。

我目前正在使用一个, 默认选项卡控制器 -- 脚手架 -- 建造者 -- CustomScrollView (SliverList + SliverFillRemaining)

SliverFillRemaining 小部件不会完全滚动,它的高度仅等于屏幕高度,即使我滚动到极端也是如此。

Before scroll

Even After Full Scroll

同样的代码在这里....

主要参考代码在 build & _columnWithTabsAndTicketDetails 函数中

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: ViewEditComplaintDetails(),
    );
  }
}

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

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

class _ViewEditComplaintDetailsState extends State<ViewEditComplaintDetails> {
  //UI variables goes below.....
  Card _complaintPreviewCard;

  //NON-UI variables goes below....

  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
  BuildContext _scaffoldContext;
  List<Widget> _productRelatedTabs;

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

    _complaintPreviewCard = _getComplaintPreviewCard();

    TextStyle _textStyle = TextStyle(fontWeight: FontWeight.w600, fontSize: 12);

    var complaintDetailsTab = Text('COMPLAINT\nDETAILS',
        textAlign: TextAlign.center, style: _textStyle);

    var contactDetailsTab = Text('CONTACT\nDETAILS',
        textAlign: TextAlign.center, style: _textStyle);

    var typeOfComplaintsTab = Text('TYPES OF\nCOMPLAINT',
        textAlign: TextAlign.center, style: _textStyle);

    var sampleDetailsTab =
        Text('SAMPLE\nDETAILS', textAlign: TextAlign.center, style: _textStyle);

    var equipAndAppliDetailsTab = Text('EQUIPMENT\nAPPLICATION DETAILS',
        textAlign: TextAlign.center, style: _textStyle);

    var uploadDocsTab = Text('UPLOADED\nDOCUMENTS',
        textAlign: TextAlign.center, style: _textStyle);

    var commentsTab =
        Text('COMMENTS', textAlign: TextAlign.center, style: _textStyle);

    _productRelatedTabs = List();
    _productRelatedTabs.add(complaintDetailsTab);
    _productRelatedTabs.add(contactDetailsTab);
    _productRelatedTabs.add(typeOfComplaintsTab);
    _productRelatedTabs.add(sampleDetailsTab);
    _productRelatedTabs.add(equipAndAppliDetailsTab);
    _productRelatedTabs.add(uploadDocsTab);
    _productRelatedTabs.add(commentsTab);
  }

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: _productRelatedTabs.length,
      child: Scaffold(
          // drawer: Drawer(child: NavigationDrawer()),
          // key: _scaffoldKey,
          // appBar: AppBarCustom(context, "View Detail", _navDrawerTap,
          //         addGulfLogoInAppBar: false)
          //     .getCustomAppBar(),
          // bottomNavigationBar: AppBottomNavigationBar(context),
          body: new Builder(builder: (BuildContext context) {
        _scaffoldContext = context;
        return _columnWithTabsAndTicketDetails();
      })),
    );
  } //build closes here....

  _columnWithTabsAndTicketDetails() {
    SliverList _sliverList = SliverList(
      delegate: SliverChildListDelegate(
        [
          //Expanded(child: _getComplaintPreviewCard(), flex: 2),
          _getComplaintPreviewCard(),
          _getTabBar(),

          // _getTabBarView()
          // Expanded(child: _getTabBarView(), flex: 5)
        ],
      ),
    );

    SliverFillRemaining tabBarBottomView =
        SliverFillRemaining(child: _getTabBarView());

    Container finalContainerWithScrollView = Container(
        child: CustomScrollView(
          slivers: [
            // Expanded(child: _sliverList, flex: 1),
            // Expanded(child: tabBarBottomView, flex: 1)
            _sliverList, tabBarBottomView
          ],
        ),
        margin: EdgeInsets.fromLTRB(0, 10, 0, 10));

    return finalContainerWithScrollView;
  } //_columnWithTabsAndTicketDetails closes here....

  _getComplaintPreviewCard() {
    ////////........1st row goes below.........\\\\\\\\\\
    // Color ticketColor = _ticketActiveColor; //Initialization...
    //TODO: Check the status of the ticket & change the color here...
    _complaintPreviewCard = Card(
      margin: EdgeInsets.fromLTRB(10, 0, 10, 0),
      // elevation: ELEVATION_APP,
      child: ClipPath(
          child: Container(
        child: _getComplaintDetails(context),
        decoration: BoxDecoration(
            border: Border(left: BorderSide(color: Colors.green, width: 5))),
      )),
    );

    return _complaintPreviewCard;
  } //_getComplaintPreviewCard closes here....

  _getComplaintDetails(BuildContext context) {
    var margin = EdgeInsets.fromLTRB(10, 0, 5, 0);
    return Container(
        // margin: EdgeInsets.fromLTRB(10, 0, 5, 0),
        padding: EdgeInsets.fromLTRB(0, 8, 0, 0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            Container(child: _complaintDetailsTopRow(), margin: margin),
            Container(child: _complaintDetailsBottomRow(), margin: margin),
            _getImagesVideoAudioCountRow(),
          ],
        ));
  } //_getComplaintDetails closes here....

  _complaintDetailsTopRow() {
    return Container(
      child: Column(
        // mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          //Complaint Title row goes below....
          _getComplaintTitleRow(),
          _getComplaintIDRow(),
        ],
      ),
    );
  } //_complaintDetailsTopRow closes here.....

  _complaintDetailsBottomRow() {
    return Container(
      margin: EdgeInsets.only(top: 15),
      child: Row(crossAxisAlignment: CrossAxisAlignment.start, children: [
        Expanded(child: _getLeftAssignmentColumn(), flex: 4),
        Container(width: 10),
        Expanded(child: _getRightAssignmentColumn(), flex: 4),
      ]),
    );
  } //_complaintDetailsBottomRow closes here....

  _getComplaintTitleRow() {
    return Container(
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisAlignment: MainAxisAlignment.start,
        children: [
          Expanded(child: Icon(Icons.ac_unit), flex: 1),
          Expanded(child: Text("Complaint Title"), flex: 15),
        ],
      ),
    );
  } //_getComplaintTitleRow closes here.....

  _getComplaintIDRow() {
    var complaintDate = "", complaintCode = "";

    return Row(
      mainAxisAlignment: MainAxisAlignment.start,
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        // SmallestText("ID : GT12345", isBlack: true, bottomMargin: 10),
        Expanded(child: Text("ID : $complaintCode"), flex: 3),
        Container(
            margin: EdgeInsets.fromLTRB(5, 0, 5, 10),
            height: 15,
            width: 1,
            color: Colors.green),
        Expanded(
          child: Text("Created on : ${complaintDate}"),
          flex: 3,
        ),

        // Expanded(child: ticketStatusText, flex: 2),
        Container(width: 5) //Adding right margin...
      ],
    );
  } //_getComplaintIDRow closes here....

  _getLeftAssignmentColumn() {
    var complaintDate = "", complaintAssignedTo = "";

    return Container(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text("Assign to : $complaintAssignedTo"),
          Text("Assign on : $complaintDate"),
        ],
      ),
    );
  } //_getLeftAssignmentColumn closes here....

  _getRightAssignmentColumn() {
    String regionName = "", status = "";

    return Container(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text("Zone $regionName"),
          Text("Status : $status"),
        ],
      ),
    );
  } //_getRightAssignmentColumn closes here....

  _getImagesVideoAudioCountRow() {
    return Container(
        padding: EdgeInsets.fromLTRB(0, 5, 0, 5),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            Expanded(
                child:
                    Container(color: Colors.green, child: Icon(Icons.ac_unit)),
                flex: 1),
            Container(width: 1, height: 45, color: Colors.red),
            Expanded(child: Container(child: Icon(Icons.ac_unit)), flex: 1),
            Container(width: 1, height: 45, color: Colors.red),
            Expanded(child: Container(child: Icon(Icons.ac_unit)), flex: 1),
          ],
        ));
  } //_getImagesVideoAudioCountRow closes here....

  _getTabBar() {
    var tabControllerAppBar = new SizedBox(
      height: 50,
      child: new Container(
        height: 50,
        color: Colors.green,
        child: new SafeArea(
          child: new TabBar(isScrollable: true, tabs: _productRelatedTabs),
        ),
      ),
    );

    return tabControllerAppBar;
  } //_getTabBar closes here.....

  _getTabBarView() {
    var tabControllerBody = TabBarView(children: [
      Container(
          margin: EdgeInsets.fromLTRB(10, 0, 10, 0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text("1"),
              TextFormField(),
              // Container(height: 15),
              Text("2"),
              TextFormField(),
              Text("3"),
              TextFormField(),
              Text("4"),
              TextFormField(),
              Text("5"),
              TextFormField(),
              Text("6"),
              TextFormField(),
              Text("7"),
              TextFormField(),
              Text("8"),
              TextFormField(),
              Text("9"),
              TextFormField(),
              Text("10"),
              TextFormField(),
              Text("11"),
              TextFormField(),
              Text("12"),
              TextFormField(),
            ],
          )),

      // new Column(
      //   children: <Widget>[new Text("Cart Page")],
      // ),

      // Container(
      //     margin:
      //         EdgeInsets.fromLTRB(_standard10Margin, 0, _standard10Margin, 0),
      //     child: ContactDetailsContainer(this, _complaintType,
      //         prefilledPackageDetails: null, prefilledProductDetails: null)),
      new Column(
        children: <Widget>[new Text("Cart Page")],
      ),
      new Column(
        children: <Widget>[new Text("Cart Page")],
      ),
      new Column(
        children: <Widget>[new Text("Lunches Page")],
      ),
      new Column(
        children: <Widget>[new Text("Lunches Page")],
      ),
      new Column(
        children: <Widget>[new Text("Lunches Page")],
      ),
      new Column(
        children: <Widget>[new Text("Lunches Page")],
      ),
    ]);

    return tabControllerBody;
  } //_getTabBarView closes here.....

} //_ViewEditComplaintDetailsState closes here....

到目前为止我尝试了什么?

  1. 在提到这个之后我已经达到了:https://stackoverflow.com/a/63305024/2975475

  2. 尝试在 SingleChildScrollView - Container - TabBarView 中添加 TabBarView 但不起作用。

  3. 尝试在 ListView 中添加 TabBarView - TabBarView 但没有奏效。

  4. 在每次点击 Tab 时删除 TabBarView 和 setState,但每次选择的选项卡都会重置为 0。

【问题讨论】:

  • 嗨 Pawan,我无法重现您遇到的错误,您能发布一个最小的可重现代码吗?
  • 好的。将发布新代码。
  • @void:请立即检查更新的代码。很抱歉打扰您。
  • 您希望Tabs 在内容滚动时保持原位吗? @Pawan
  • 不,标签也会滚动

标签: flutter flutter-layout


【解决方案1】:

如上面cmets中提到的,滚动TabBarView内容时,还需要Tabs滚动。

我会考虑在这种情况下使用NestedScrollView。点击此处阅读更多关于NestedScrollView的信息。

我添加了一个演示,以您的代码为例,说明如何使用NestedScrollView

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

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

class _ViewEditComplaintDetailsState extends State<ViewEditComplaintDetails> {
  //UI variables goes below.....
  Card _complaintPreviewCard;

  //NON-UI variables goes below....

  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
  BuildContext _scaffoldContext;
  List<Widget> _productRelatedTabs;

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

    _complaintPreviewCard = _getComplaintPreviewCard();

    TextStyle _textStyle = TextStyle(fontWeight: FontWeight.w600, fontSize: 12);

    var complaintDetailsTab = Text('COMPLAINT\nDETAILS',
        textAlign: TextAlign.center, style: _textStyle);

    var contactDetailsTab = Text('CONTACT\nDETAILS',
        textAlign: TextAlign.center, style: _textStyle);

    var typeOfComplaintsTab = Text('TYPES OF\nCOMPLAINT',
        textAlign: TextAlign.center, style: _textStyle);

    var sampleDetailsTab =
        Text('SAMPLE\nDETAILS', textAlign: TextAlign.center, style: _textStyle);

    var equipAndAppliDetailsTab = Text('EQUIPMENT\nAPPLICATION DETAILS',
        textAlign: TextAlign.center, style: _textStyle);

    var uploadDocsTab = Text('UPLOADED\nDOCUMENTS',
        textAlign: TextAlign.center, style: _textStyle);

    var commentsTab =
        Text('COMMENTS', textAlign: TextAlign.center, style: _textStyle);

    _productRelatedTabs = List();
    _productRelatedTabs.add(complaintDetailsTab);
    _productRelatedTabs.add(contactDetailsTab);
    _productRelatedTabs.add(typeOfComplaintsTab);
    _productRelatedTabs.add(sampleDetailsTab);
    _productRelatedTabs.add(equipAndAppliDetailsTab);
    _productRelatedTabs.add(uploadDocsTab);
    _productRelatedTabs.add(commentsTab);
  }

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: _productRelatedTabs.length,
      child: Scaffold(
          // drawer: Drawer(child: NavigationDrawer()),
          // key: _scaffoldKey,
          // appBar: AppBarCustom(context, "View Detail", _navDrawerTap,
          //         addGulfLogoInAppBar: false)
          //     .getCustomAppBar(),
          // bottomNavigationBar: AppBottomNavigationBar(context),
          body: new Builder(builder: (BuildContext context) {
        _scaffoldContext = context;
        return NestedScrollView(
          headerSliverBuilder: (context, value) {
            return [
              // header
              SliverList(
                delegate: SliverChildListDelegate(
                  [
                    //Expanded(child: _getComplaintPreviewCard(), flex: 2),
                    _getComplaintPreviewCard(),
                    _getTabBar(),

                    // _getTabBarView()
                    // Expanded(child: _getTabBarView(), flex: 5)
                  ],
                ),
              ),
            ];
          },
          // tab bar view
          body: _getTabBarView(),
        );
      })),
    );
  } //build closes here....

  _getComplaintPreviewCard() {
    ////////........1st row goes below.........\\\\\\\\\\
    // Color ticketColor = _ticketActiveColor; //Initialization...
    //TODO: Check the status of the ticket & change the color here...
    _complaintPreviewCard = Card(
      margin: EdgeInsets.fromLTRB(10, 0, 10, 0),
      // elevation: ELEVATION_APP,
      child: ClipPath(
          child: Container(
        child: _getComplaintDetails(context),
        decoration: BoxDecoration(
            border: Border(left: BorderSide(color: Colors.green, width: 5))),
      )),
    );

    return _complaintPreviewCard;
  } //_getComplaintPreviewCard closes here....

  _getComplaintDetails(BuildContext context) {
    var margin = EdgeInsets.fromLTRB(10, 0, 5, 0);
    return Container(
        // margin: EdgeInsets.fromLTRB(10, 0, 5, 0),
        padding: EdgeInsets.fromLTRB(0, 8, 0, 0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            Container(child: _complaintDetailsTopRow(), margin: margin),
            Container(child: _complaintDetailsBottomRow(), margin: margin),
            _getImagesVideoAudioCountRow(),
          ],
        ));
  } //_getComplaintDetails closes here....

  _complaintDetailsTopRow() {
    return Container(
      child: Column(
        // mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          //Complaint Title row goes below....
          _getComplaintTitleRow(),
          _getComplaintIDRow(),
        ],
      ),
    );
  } //_complaintDetailsTopRow closes here.....

  _complaintDetailsBottomRow() {
    return Container(
      margin: EdgeInsets.only(top: 15),
      child: Row(crossAxisAlignment: CrossAxisAlignment.start, children: [
        Expanded(child: _getLeftAssignmentColumn(), flex: 4),
        Container(width: 10),
        Expanded(child: _getRightAssignmentColumn(), flex: 4),
      ]),
    );
  } //_complaintDetailsBottomRow closes here....

  _getComplaintTitleRow() {
    return Container(
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisAlignment: MainAxisAlignment.start,
        children: [
          Expanded(child: Icon(Icons.ac_unit), flex: 1),
          Expanded(child: Text("Complaint Title"), flex: 15),
        ],
      ),
    );
  } //_getComplaintTitleRow closes here.....

  _getComplaintIDRow() {
    var complaintDate = "", complaintCode = "";

    return Row(
      mainAxisAlignment: MainAxisAlignment.start,
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        // SmallestText("ID : GT12345", isBlack: true, bottomMargin: 10),
        Expanded(child: Text("ID : $complaintCode"), flex: 3),
        Container(
            margin: EdgeInsets.fromLTRB(5, 0, 5, 10),
            height: 15,
            width: 1,
            color: Colors.green),
        Expanded(
          child: Text("Created on : ${complaintDate}"),
          flex: 3,
        ),

        // Expanded(child: ticketStatusText, flex: 2),
        Container(width: 5) //Adding right margin...
      ],
    );
  } //_getComplaintIDRow closes here....

  _getLeftAssignmentColumn() {
    var complaintDate = "", complaintAssignedTo = "";

    return Container(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text("Assign to : $complaintAssignedTo"),
          Text("Assign on : $complaintDate"),
        ],
      ),
    );
  } //_getLeftAssignmentColumn closes here....

  _getRightAssignmentColumn() {
    String regionName = "", status = "";

    return Container(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text("Zone $regionName"),
          Text("Status : $status"),
        ],
      ),
    );
  } //_getRightAssignmentColumn closes here....

  _getImagesVideoAudioCountRow() {
    return Container(
        padding: EdgeInsets.fromLTRB(0, 5, 0, 5),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            Expanded(
                child:
                    Container(color: Colors.green, child: Icon(Icons.ac_unit)),
                flex: 1),
            Container(width: 1, height: 45, color: Colors.red),
            Expanded(child: Container(child: Icon(Icons.ac_unit)), flex: 1),
            Container(width: 1, height: 45, color: Colors.red),
            Expanded(child: Container(child: Icon(Icons.ac_unit)), flex: 1),
          ],
        ));
  } //_getImagesVideoAudioCountRow closes here....

  _getTabBar() {
    var tabControllerAppBar = new SizedBox(
      height: 50,
      child: new Container(
        height: 50,
        color: Colors.green,
        child: new SafeArea(
          child: new TabBar(isScrollable: true, tabs: _productRelatedTabs),
        ),
      ),
    );

    return tabControllerAppBar;
  } //_getTabBar closes here.....

  _getTabBarView() {
    var tabControllerBody = TabBarView(children: [
      Container(
          margin: EdgeInsets.fromLTRB(10, 0, 10, 0),
          child: SingleChildScrollView(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text("1"),
                TextFormField(),
                // Container(height: 15),
                Text("2"),
                TextFormField(),
                Text("3"),
                TextFormField(),
                Text("4"),
                TextFormField(),
                Text("5"),
                TextFormField(),
                Text("6"),
                TextFormField(),
                Text("7"),
                TextFormField(),
                Text("8"),
                TextFormField(),
                Text("9"),
                TextFormField(),
                Text("10"),
                TextFormField(),
                Text("11"),
                TextFormField(),
                Text("12"),
                TextFormField(),
              ],
            ),
          )),

      // new Column(
      //   children: <Widget>[new Text("Cart Page")],
      // ),

      // Container(
      //     margin:
      //         EdgeInsets.fromLTRB(_standard10Margin, 0, _standard10Margin, 0),
      //     child: ContactDetailsContainer(this, _complaintType,
      //         prefilledPackageDetails: null, prefilledProductDetails: null)),
      new Column(
        children: <Widget>[new Text("Cart Page")],
      ),
      new Column(
        children: <Widget>[new Text("Cart Page")],
      ),
      new Column(
        children: <Widget>[new Text("Lunches Page")],
      ),
      new Column(
        children: <Widget>[new Text("Lunches Page")],
      ),
      new Column(
        children: <Widget>[new Text("Lunches Page")],
      ),
      new Column(
        children: <Widget>[new Text("Lunches Page")],
      ),
    ]);

    return tabControllerBody;
  } //_getTabBarView closes here.....

} //_ViewEditComplaintDetai

结果:

【讨论】:

    猜你喜欢
    • 2022-08-03
    • 2020-11-27
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 1970-01-01
    • 2020-09-30
    • 2020-12-29
    • 2020-11-22
    相关资源
    最近更新 更多