使 TabBarView 占据屏幕的剩余部分

问题描述 投票:0回答:1

我想在占据屏幕剩余空间的屏幕点中显示 TabBar。这样做时,我的目标是在该

GridView
 的两个选项卡中显示两个 
TabBar

当我使用

Expanded
小部件时,它会导致应用程序崩溃,只有当我使用具有高度限制的
SizedBox
时,它才有效。

这是代码

import 'package:bespoked_1_1/utils/constants.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

class SellersHomePage extends StatefulWidget {
  const SellersHomePage({super.key});

  @override
  State<SellersHomePage> createState() => _SellersHomePageState();
}

class _SellersHomePageState extends State<SellersHomePage> {
  @override
  Widget build(BuildContext context) {
    final screenWidth = MediaQuery.of(context).size.width;
    final screenHeight = MediaQuery.of(context).size.height;
    return Scaffold(
      appBar: AppBar(
        title: Text('Epoxy Forever'),
        centerTitle: true,
        actions: [
          IconButton(
            onPressed: () {},
            icon: Icon(
              Icons.ios_share,
            ),
          ),
          IconButton(
            onPressed: () {},
            icon: Icon(
              Icons.shopping_cart_outlined,
            ),
          ),
        ],
      ),
      body: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Stack(
            children: [
              SizedBox(
                height: screenHeight * 0.3,
                width: screenWidth,
                child: ShaderMask(
                  shaderCallback: (rect) {
                    return LinearGradient(
                      begin: Alignment.topCenter,
                      end: Alignment.bottomCenter,
                      colors: const [Colors.black, Colors.transparent],
                    ).createShader(
                        Rect.fromLTRB(0, 0, rect.width, rect.height));
                  },
                  blendMode: BlendMode.dstIn,
                  child: Image(
                    fit: BoxFit
                        .cover, //TODO: Give the option to change the fit of the image
                    height: screenHeight * 0.2,
                    image: NetworkImage(
                        'https://img.freepik.com/free-photo/carpenter-cutting-mdf-board-inside-workshop_23-2149451051.jpg'),
                  ),
                ),
              ),

              //sellers logo and details
              Positioned(
                top: 20,
                left: 0,
                right: 0,
                child: Padding(
                  padding: const EdgeInsets.all(20.0),
                  child: Column(
                    children: const [
                      //profile image
                      CircleAvatar(
                        radius: 50,
                        backgroundImage: NetworkImage(
                            'https://t3.ftcdn.net/jpg/01/37/76/72/360_F_137767250_pocwIHgKu5rDuYFDNCTNcPy77gHb1lfh.jpg'),
                      ),

                      //name
                      Text(
                        'Karls Carpentry',
                        style: TextStyle(
                            fontWeight: FontWeight.bold, fontSize: 24),
                      ),

                      //sub heading
                      Text(
                        'Specialist in Fine custom furniture and upholstery',
                        style: TextStyle(fontSize: 16),
                        textAlign: TextAlign.center,
                      ),
                    ],
                  ),
                ),
              ),
            ],
          ),

          //business stats
          Center(
            child: Container(
              margin: EdgeInsets.symmetric(horizontal: 30),
              decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(25), color: Colors.grey),
              padding: EdgeInsets.symmetric(horizontal: 30, vertical: 10),
              child: const Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  //avg rating
                  Column(
                    children: [
                      Text(
                        '4.8',
                        style: TextStyle(fontSize: 24),
                      ),
                      Text('Avg Rating')
                    ],
                  ),

                  //followers
                  Column(
                    children: [
                      Text(
                        '28',
                        style: TextStyle(fontSize: 24),
                      ),
                      Text('Avg Rating')
                    ],
                  ),

                  //callouts and items sold
                  Column(
                    children: [
                      Text(
                        '200',
                        style: TextStyle(fontSize: 24),
                      ),
                      Text('Avg Rating')
                    ],
                  )
                ],
              ),
            ),
          ),

          DefaultTabController(
            length: 3,
            child: Column(
              children: [
                //tabs
                TabBar(indicatorSize: TabBarIndicatorSize.tab, tabs: [
                  Tab(
                    text: 'Shop',
                  ),
                  Tab(
                    text: 'Posts',
                  ),
                  Tab(
                    text: 'About',
                  ),
                ]),

                //tabviews
                TabBarView(children: [
                  Icon(Icons.shop),
                  Icon(Icons.image),
                  Icon(Icons.info)
                ])
              ],
            ),
          ),
        ],
      ),
    );
  }
}
flutter dart mobile
1个回答
1
投票

尝试以下操作,这是您的代码,但添加了您想要的内容。

要使

TabBar
分配屏幕的剩余空间,请使用
Expanded
小部件将其包裹起来。

此外,还有两个选项卡包含可滚动的网格布局:

class SellersHomePage extends StatefulWidget {
  const SellersHomePage({super.key});

  @override
  State<SellersHomePage> createState() => _SellersHomePageState();
}

class _SellersHomePageState extends State<SellersHomePage> {
  @override
  Widget build(BuildContext context) {
    final screenWidth = MediaQuery.of(context).size.width;
    final screenHeight = MediaQuery.of(context).size.height;
    return DefaultTabController(
      length: 3,
      child: Scaffold(
        appBar: AppBar(
          title: Text('Epoxy Forever'),
          centerTitle: true,
          actions: [
            IconButton(
              onPressed: () {},
              icon: Icon(
                Icons.ios_share,
              ),
            ),
            IconButton(
              onPressed: () {},
              icon: Icon(
                Icons.shopping_cart_outlined,
              ),
            ),
          ],
        ),
        body: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Stack(
              children: [
                SizedBox(
                  height: screenHeight * 0.3,
                  width: screenWidth,
                  child: ShaderMask(
                    shaderCallback: (rect) {
                      return LinearGradient(
                        begin: Alignment.topCenter,
                        end: Alignment.bottomCenter,
                        colors: const [Colors.black, Colors.transparent],
                      ).createShader(
                          Rect.fromLTRB(0, 0, rect.width, rect.height));
                    },
                    blendMode: BlendMode.dstIn,
                    child: Image(
                      fit: BoxFit
                          .cover, //TODO: Give the option to change the fit of the image
                      height: screenHeight * 0.2,
                      image: NetworkImage(
                          'https://img.freepik.com/free-photo/carpenter-cutting-mdf-board-inside-workshop_23-2149451051.jpg'),
                    ),
                  ),
                ),

                //sellers logo and details
                Positioned(
                  top: 20,
                  left: 0,
                  right: 0,
                  child: Padding(
                    padding: const EdgeInsets.all(20.0),
                    child: Column(
                      children: const [
                        //profile image
                        CircleAvatar(
                          radius: 50,
                          backgroundImage: NetworkImage(
                              'https://t3.ftcdn.net/jpg/01/37/76/72/360_F_137767250_pocwIHgKu5rDuYFDNCTNcPy77gHb1lfh.jpg'),
                        ),

                        //name
                        Text(
                          'Karls Carpentry',
                          style: TextStyle(
                              fontWeight: FontWeight.bold, fontSize: 24),
                        ),

                        //sub heading
                        Text(
                          'Specialist in Fine custom furniture and upholstery',
                          style: TextStyle(fontSize: 16),
                          textAlign: TextAlign.center,
                        ),
                      ],
                    ),
                  ),
                ),
              ],
            ),

            //business stats
            Center(
              child: Container(
                margin: EdgeInsets.symmetric(horizontal: 30),
                decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(25), color: Colors.grey),
                padding: EdgeInsets.symmetric(horizontal: 30, vertical: 10),
                child:  Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    //avg rating
                    Column(
                      children: [
                        Text(
                          '4.8',
                          style: TextStyle(fontSize: 24),
                        ),
                        Text('Avg Rating')
                      ],
                    ),

                    //followers
                    Column(
                      children: [
                        Text(
                          '28',
                          style: TextStyle(fontSize: 24),
                        ),
                        Text('Avg Rating')
                      ],
                    ),

                    //callouts and items sold
                    Column(
                      children: [
                        Text(
                          '200',
                          style: TextStyle(fontSize: 24),
                        ),
                        Text('Avg Rating')
                      ],
                    )
                  ],
                ),
              ),
            ),

            Expanded(
              child: Column(
                children: [
                  //tabs
                  TabBar(indicatorSize: TabBarIndicatorSize.tab, tabs: [
                    Tab(
                      text: 'Shop',
                    
                    ),
                    Tab(
                      text: 'Posts',
                    ),
                    Tab(
                      text: 'About',
                    ),
                  ]),

                  //tabviews
                  Expanded(
                    child: TabBarView(children: [
                      GridView.builder(
                        itemBuilder: (context,index)=>Container(color: Colors.yellow),
                        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                          crossAxisCount: 3,
                          crossAxisSpacing: 10,
                          mainAxisSpacing: 10,
                        ),
                      ),
                      

                      GridView.builder(
                        itemBuilder: (context,index)=>Container(color: Colors.purple),
                        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                          crossAxisCount: 3,
                          crossAxisSpacing: 10,
                          mainAxisSpacing: 10,
                        ),
                      ),
                      Icon(Icons.info)
                    ]),
                  )
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

第一个选项卡

第二个选项卡

注意:选项卡带有蓝色实线下划线,但它们的标签需要样式,请在您的主题中处理。

© www.soinside.com 2019 - 2024. All rights reserved.