flutter入门系列教程<三>:tabbar的高度自适用,支持无限滚动

背景

在之前的文章中,简介了tabbar组件的使用,它通常用于顶部放置tabbar标签页头,内容全部都是TabbarView的全部内容,且内容通常是占满屏幕的(尽可能大),如下:

但是有时候我们需要在文章的中间部分使用tabbar,之前也简介了封装的方法,当时的思路是给tabbarView限制高度、或者使用expand组件包裹,但这样也不是很灵活。

因为,如果tabbarView下面还有其他组件,那么tabbarView的高度就被限制死了。

那么,能否实现tabbarView无论在哪里,上面下面是否有组件时,其高度都能自适用呢?

自定义tabbar

由于tabbarView组件的特性使然,它必须有固定的高度、或者声明为占据尽可能大的高度,所以如果要让tabbar高度自适用,那就得自己封装,即:不使用tabbarView组件,效果图如下:

自定义tabbar源码

以下仅为示例代码,但足可以应付开发中的大部分需求,仅供参考:

dart 复制代码
import 'package:flutter/material.dart';

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

  @override
  State<CustomTabBarExample> createState() => _CustomTabBarExampleState();
}

class _CustomTabBarExampleState extends State<CustomTabBarExample> {
  int _selectedTabIndex = 0;

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 3, // Tab 的数量
      child: Scaffold(
        appBar: AppBar(
          title: const Text('自适用的tabbar'),
        ),
        body: SingleChildScrollView(
          child: Column(
            children: [
              // 顶部部分,可自定义内容
              Container(
                height: 100,
                color: Colors.blue,
                child: const Center(
                  child: Text('Top Section'),
                ),
              ),
              // TabBar
              TabBar(
                onTap: (index) {
                  setState(() {
                    _selectedTabIndex = index;
                  });
                },
                tabs: const [
                  Tab(text: 'Tab 1'),
                  Tab(text: 'Tab 2'),
                  Tab(text: 'Tab 3'),
                ],
              ),
              // 根据选中的 Tab 索引显示不同的内容
              _buildTabContent(_selectedTabIndex),
              // 底部部分,可自定义内容
              Container(
                height: 100,
                color: Colors.orange,
                child: const Center(
                  child: Text('Bottom Section'),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildTabContent(int index) {
    switch (index) {
      case 0:
        return Container(
          height: 70,
          color: Colors.red,
          child: const Center(
            child: Text('Tab 1 Content'),
          ),
        );
      case 1:
        return Container(
          height: 800,
          color: Colors.green,
          child: const Center(
            child: Text('Tab 2 Content'),
          ),
        );
      case 2:
        return Container(
          height: 150,
          color: Colors.yellow,
          child: const Center(
            child: Text('Tab 3 Content'),
          ),
        );
      default:
        return Container();
    }
  }
}
相关推荐
轻语呢喃6 分钟前
JavaScript :字符串模板——优雅编程的基石
前端·javascript·后端
coding随想19 分钟前
JavaScript中的BOM:Window对象全解析
开发语言·javascript·ecmascript
難釋懷20 分钟前
TypeScript-webpack
javascript·webpack·typescript
Rockson24 分钟前
使用Ruby接入实时行情API教程
javascript·python
前端小巷子2 小时前
Web开发中的文件上传
前端·javascript·面试
上单带刀不带妹2 小时前
手写 Vue 中虚拟 DOM 到真实 DOM 的完整过程
开发语言·前端·javascript·vue.js·前端框架
前端风云志3 小时前
typescript结构化类型应用两例
javascript
gnip4 小时前
总结一期正则表达式
javascript·正则表达式
爱分享的程序员4 小时前
前端面试专栏-算法篇:18. 查找算法(二分查找、哈希查找)
前端·javascript·node.js
翻滚吧键盘4 小时前
vue 条件渲染(v-if v-else-if v-else v-show)
前端·javascript·vue.js