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();
    }
  }
}
相关推荐
晓得迷路了4 分钟前
栗子前端技术周刊第 83 期 - Rolldown-Vite、Angular v20、Docusaurus 3.8...
前端·javascript·vite
独立开阀者_FwtCoder5 分钟前
如何让 Cursor AI Agent始终遵守项目规范:使用自动规则生成技术
java·前端·javascript
独立开阀者_FwtCoder9 分钟前
尤雨溪宣布:Vue 3.6 重大更新!Vite 将彻底重写!
前端·javascript·后端
张风捷特烈17 分钟前
每日一题 Flutter#1 | 说说你对声明式 UI 的理解
android·flutter
江城开朗的豌豆35 分钟前
JavaScript篇:如何实现add(1)(2)(3)()=6?揭秘链式调用的终极奥义!
前端·javascript·面试
江城开朗的豌豆40 分钟前
JavaScript篇:GET、POST、PUT...傻傻分不清?一篇文章带你玩转HTTP请求!
前端·javascript·面试
恋猫de小郭2 小时前
Flutter 官方多窗口体验 ,为什么 Flutter 推进那么慢,而 CMP 却支持那么快
android·前端·flutter
烛阴10 小时前
Date-fns教程:现代JavaScript日期处理从入门到精通
前端·javascript
小蜜蜂嗡嗡11 小时前
flutter项目迁移空安全
javascript·安全·flutter
江城开朗的豌豆12 小时前
JavaScript篇:a==0 && a==1 居然能成立?揭秘JS中的"魔法"比较
前端·javascript·面试