TabBar和TabBarView实现顶部滑动导航

 home.dart子页面主要代码:

import 'package:flutter/material.dart';

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

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage>
    with SingleTickerProviderStateMixin {
  late TabController _tabController;

  //生命周期函数:初始化时触发
  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 9, vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        //背景颜色
        backgroundColor: Colors.white,
        //阴影高度
        elevation: 0,
        title: TabBar(
          //是否可滚动
          isScrollable: true,
          controller: _tabController,
          //指示器高度
          indicatorWeight: 1,
          //指示器边距
          // indicatorPadding: const EdgeInsets.all(2),
          //选中字体颜色
          labelColor: Colors.white,
          //未选中字体颜色
          unselectedLabelColor: Colors.grey,
          //指示器宽度,默认tab:撑满选项卡宽度; label:宽度跟随内容,不撑满选项卡
          // indicatorSize: TabBarIndicatorSize.label,
          //指示器颜色
          // indicatorColor: Colors.white,
          //指示器Decoration
          indicator: BoxDecoration(
            color: Colors.blue,
            borderRadius: BorderRadius.circular(10),
          ),
          //选中label样式
          labelStyle: const TextStyle(fontSize: 15),
          //未选中label样式
          unselectedLabelStyle: const TextStyle(fontSize: 14),
          tabs: const [
            Tab(
              child: Text("关注"),
            ),
            Tab(
              child: Text("热门"),
            ),
            Tab(
              child: Text("视频"),
            ),
            Tab(
              child: Text("关注"),
            ),
            Tab(
              child: Text("热门"),
            ),
            Tab(
              child: Text("视频"),
            ),
            Tab(
              child: Text("关注"),
            ),
            Tab(
              child: Text("热门"),
            ),
            Tab(
              child: Text("视频"),
            ),
          ],
        ),
      ),
      body: TabBarView(
        controller: _tabController,
        children: const [
          Center(
            child: Text("关注"),
          ),
          Center(
            child: Text("热门"),
          ),
          Center(
            child: Text("视频"),
          ),
          Center(
            child: Text("关注"),
          ),
          Center(
            child: Text("热门"),
          ),
          Center(
            child: Text("视频"),
          ),
          Center(
            child: Text("关注"),
          ),
          Center(
            child: Text("热门"),
          ),
          Center(
            child: Text("视频"),
          ),
        ],
      ),
    );
  }
}

首先需要with SingleTickerProviderStateMixin方法,然后initState生命周期函数中设置Tab长度,最后在Scaffold中设置TabBar和TabBarView。

appBar高度设置:

appBar: PreferredSize(
  //appBar高度设置
  preferredSize: const Size.fromHeight(40),
  child: AppBar(
    //背景颜色
    backgroundColor: Colors.transparent,
    //阴影高度
    elevation: 0,
    title: TabBar(
      //是否可滚动
      isScrollable: true,
      controller: _tabController,
      //指示器高度
      // indicatorWeight: 1,
      //指示器边距
      indicatorPadding: const EdgeInsets.all(5),
      //选中字体颜色
      labelColor: Colors.red,
      //指示器颜色
      indicatorColor: Colors.red,
      //指示器Decoration
      /* indicator: BoxDecoration(
        color: Colors.blue,
        borderRadius: BorderRadius.circular(10),
      ),*/
      //未选中字体颜色
      unselectedLabelColor: Colors.black,
      //指示器宽度,默认tab:撑满选项卡宽度; label:宽度跟随内容,不撑满选项卡
      indicatorSize: TabBarIndicatorSize.label,
      //选中label样式
      labelStyle: const TextStyle(fontSize: 15),
      //未选中label样式
      unselectedLabelStyle: const TextStyle(fontSize: 15),
      //只监听点击事件,多次点击同一个tab且每次都会监听
      /*onTap: (index) {
        print(index);
      },*/
      tabs: const [
        Tab(
          child: Text("关注"),
        ),
        Tab(
          child: Text("热门"),
        ),
        Tab(
          child: Text("视频"),
        ),
        Tab(
          child: Text("关注"),
        ),
        Tab(
          child: Text("热门"),
        ),
        Tab(
          child: Text("视频"),
        ),
        Tab(
          child: Text("关注"),
        ),
        Tab(
          child: Text("热门"),
        ),
        Tab(
          child: Text("视频"),
        ),
      ],
    ),
  ),
),

AppBar外嵌套PreferredSize组件,PreferredSize组件中通过preferredSize: const Size.fromHeight(40),属性设置AppBar的高度。

onTap属性只监听点击事件,多次点击同一个tab且每次都会监听。

TabController监听事件:

@override
void initState() {
  super.initState();
  _tabController = TabController(length: 9, vsync: this);
  //监听_tabController事件的改变(滑动和点击都会监听,且同一tab多次点击只监听一次)
  _tabController.addListener(() {
    if (_tabController.animation?.value == _tabController.index) {
      print(_tabController.index);
    }
  });
}

///生命周期函数,组件销毁时触发
@override
void dispose() {
  super.dispose();
  _tabController.dispose();
}

TabController滑动和点击都会监听,且同一tab多次点击只监听一次。

dispose()为生命周期销毁函数。

TabBar下的主要属性代码中已注释,更多属性请参考源码:

const TabBar({
    super.key,
    required this.tabs,
    this.controller,
    this.isScrollable = false,
    this.padding,
    this.indicatorColor,
    this.automaticIndicatorColorAdjustment = true,
    this.indicatorWeight = 2.0,
    this.indicatorPadding = EdgeInsets.zero,
    this.indicator,
    this.indicatorSize,
    this.dividerColor,
    this.labelColor,
    this.labelStyle,
    this.labelPadding,
    this.unselectedLabelColor,
    this.unselectedLabelStyle,
    this.dragStartBehavior = DragStartBehavior.start,
    this.overlayColor,
    this.mouseCursor,
    this.enableFeedback,
    this.onTap,
    this.physics,
    this.splashFactory,
    this.splashBorderRadius,
  }) : _isPrimary = true,
       assert(indicator != null || (indicatorWeight > 0.0));

main.dart首页代码:

import 'package:flutter/material.dart';
import 'package:flutter_demo/tabs/category.dart';
import 'package:flutter_demo/tabs/home.dart';
import 'package:flutter_demo/tabs/people.dart';
import 'package:flutter_demo/tabs/setting.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      //隐藏DEBUG图标
      debugShowCheckedModeBanner: false,
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const Scaffold(
        body: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const Tabs();
  }
}

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

  @override
  State<Tabs> createState() => _TabsState();
}

class _TabsState extends State<Tabs> {
  int currentIndex = 0;

  List<Widget> pages = const [
    HomePage(),
    CategoryPage(),
    SettingPage(),
    PeoplePage()
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Flutter"),
      ),
      body: pages[currentIndex],
      drawer: const Drawer(
        child: Column(
          children: [
            Row(
              children: [
                Expanded(
                  flex: 1,
                  child: UserAccountsDrawerHeader(
                    accountName: Text("张三"),
                    accountEmail: Text("xxx@qq.com"),
                    currentAccountPicture: CircleAvatar(
                      backgroundImage: NetworkImage(
                          "https://www.itying.com/images/flutter/1.png"),
                    ),
                    decoration: BoxDecoration(
                      image: DecorationImage(
                        image: NetworkImage(
                            "https://www.itying.com/images/flutter/2.png"),
                        fit: BoxFit.cover,
                      ),
                    ),
                  ),
                ),
              ],
            ),
            ListTile(
              leading: CircleAvatar(
                child: Icon(
                  Icons.people,
                ),
              ),
              title: Text("个人中心"),
            ),
            Divider(),
            ListTile(
              leading: CircleAvatar(
                child: Icon(
                  Icons.settings,
                ),
              ),
              title: Text("系统设置"),
            )
          ],
        ),
      ),
      bottomNavigationBar: BottomNavigationBar(
        //选中菜单颜色
        fixedColor: Colors.blue,
        //图标大小,默认24.0
        iconSize: 30,
        //第几个菜单选中
        currentIndex: currentIndex,
        //当item数量大于3个时需要设置type属性
        type: BottomNavigationBarType.fixed,
        unselectedItemColor: Colors.grey.shade600,
        onTap: (index) {
          setState(() {
            currentIndex = index;
          });
        },
        items: const [
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: "首页",
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.category),
            label: "分类",
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.settings),
            label: "设置",
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.people),
            label: "用户",
          ),
        ],
      ),
    );
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/40773.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

前端 | (六)CSS盒子模型 | 尚硅谷前端html+css零基础教程2023最新

学习来源&#xff1a;尚硅谷前端htmlcss零基础教程&#xff0c;2023最新前端开发html5css3视频 文章目录 &#x1f4da;元素的显示模式&#x1f407;CSS长度单位&#x1f407;元素的显示模式⭐️块元素&#xff08;block&#xff09;⭐️行内元素&#xff08;inline&#xff09…

mac 下 geoserver 安装

一、去官网下载geoserver https://geoserver.org/ 选择一个版本&#xff0c;然后点进去 二、需要配置java环境和设置geoserver 环境变量 1&#xff09;、java 环境安装 Java Downloads | Oracle 中国 2&#xff09;、环境变量设置 1.打开终端&#xff1a;command 空格键 2…

一道SQL题

有个搞数仓的朋友不知道从哪儿弄了个题。。。 做了做体验了一下。。。 记录记录。 分析 要保证每天都要做新题 5天必须都做题&#xff0c;不然GG 最后一天必须做新题&#xff0c;如果最后一天做新题了&#xff0c;前面那几天没做新题&#xff0c;做的是老题 最后一天&#…

STM32使用高级定时器输出互补pwm波

STM32使用高级定时器输出互补pwm波 前言硬件和软件cubemx新建工程打开Debug模式配置时钟源六大时钟的作用选择Crystal/Ceramic Resonator&#xff0c;即使用外部晶振作为HSE的时钟源。 配置时钟配置高级定时器TIM8和通用定时器TIM3这里大概解释一下配置pwm输出用到的几个参数我…

git clone 或者是vscode clone 时遇到the remote end hung up unexpectedly

fatal: the remote end hung up unexpectedly fatal: early EOF fatal: index-pack failed使用git clone总是报错 查看原因有三种可能&#xff1a;要么是缓存不够&#xff0c;要么是网络不行&#xff0c;要么墙的原因。 如果是网络不行&#xff0c;可以配置git的最低速度和最…

postgresql导入导出数据库的一些问题

新建一个数据库 别忘了添加空间数据的扩展 备份之前的数据库 注意一定要自定义表&#xff0c;去掉 spatial_ref_sys &#xff0c;要不然需要先drop在创建&#xff0c;可能会报错。 一般不会去导函数&#xff0c;如果有个别自己创建的函数可以手动复制一下&#xff0c;全部导的话…

SQL 上升的温度

197 上升的温度 SQL架构 表&#xff1a; Weather ---------------------- | Column Name | Type | ---------------------- | id | int | | recordDate | date | | temperature | int | ---------------------- id 是这个表的主键 该表包含特定日期的温度信息 编写一个 SQL …

第108天:免杀对抗-Python混淆算法反序列化打包生成器Py2exeNuitka

知识点 #知识点&#xff1a; 1、Python-对执行代码做文章 2、Python-对shellcode做文章 3、Python-对代码打包器做文章#章节点&#xff1a; 编译代码面-ShellCode-混淆 编译代码面-编辑执行器-编写 编译代码面-分离加载器-编写 程序文件面-特征码定位-修改 程序文件面-加壳花指…

《面试1v1》Kafka基础

&#x1f345; 作者简介&#xff1a;王哥&#xff0c;CSDN2022博客总榜Top100&#x1f3c6;、博客专家&#x1f4aa; &#x1f345; 技术交流&#xff1a;定期更新Java硬核干货&#xff0c;不定期送书活动 &#x1f345; 王哥多年工作总结&#xff1a;Java学习路线总结&#xf…

Modbus TCP/BACnet IP/MQTT物联网网关IOT-810介绍及其典型应用

伴随着计算机技术以及互联网的发展&#xff0c;物联网这个概念已经逐渐进入我们的日常生活&#xff0c;例如智能泊车&#xff0c;智能家居&#xff0c;智能照明&#xff0c;智能楼宇等。智能楼宇是将传统的楼宇自控系统与物联网技术相融合&#xff0c;把系统中常见的传感器、设…

kotlin基础

val和var的区别 var是一个可变变量&#xff0c;这是一个可以通过重新分配来更改为另一个值的变量。这种声明变量的方式和java中声明变量的方式一样。 val是一个只读变量&#xff0c;这种声明变量的方式相当于java中的final变量。一个val创建的时候必须初始化&#xff0c;因为…

【Hippo4j监控Web容器Tomcat线程池】

&#x1f680; 线程池管理工具-Hippo4j &#x1f680; &#x1f332; AI工具、AI绘图、AI专栏 &#x1f340; &#x1f332; 如果你想学到最前沿、最火爆的技术&#xff0c;赶快加入吧✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;CSDN-Java领域优质创作者&#…

k8s与集群管理

从docker讲起 终于有人把 Docker 讲清楚了&#xff0c;万字详解&#xff01; Docker资源&#xff08;CPU/内存/磁盘IO/GPU&#xff09;限制与分配指南 默认情况下&#xff0c;Docker容器是没有资源限制的&#xff0c;它会尽可能地使用宿主机能够分配给它的资源。如果不对容器资…

ylb-接口6验证手机号是否注册

总览&#xff1a; 1、service处理 在api模块下service包&#xff0c;创建一个UserService接口&#xff1a;&#xff08;根据手机号查询数据queryByPhone(String phone)&#xff09; package com.bjpowernode.api.service;import com.bjpowernode.api.model.User; import co…

如何使用Spring Boot实现分页和排序?

使用Spring Boot实现分页和排序需要借助Spring Data JPA。Spring Data JPA是Spring Data项目中的一个模块&#xff0c;提供了简化数据访问层的功能&#xff0c;包括分页和排序。 接下来我们通过一段Java代码&#xff0c;展示如何使用Spring Data JPA和Spring Boot实现分页和排…

el-progress组件使用,样式修改,自定义文字

正常的el-progress显示是这样的 修改后 自动计算percentage&#xff0c;format自定义显示文字 <template><div><div class"content-view"><div v-for"(item, index) in progressList" class"item-view"><el-prog…

单轴机器人的结构与特点

单轴机器人是由马达驱动的移动平台&#xff0c;由滚珠螺杆和 U型线性滑轨导引构成&#xff0c;其滑座同时为滚珠螺杆的驱动螺帽及线性滑轨的导引滑块&#xff0c;可用半导体、光电、交通运输业、环保节能产业、精密工具机、机械产业、智慧自动化、生技医疗上。 相对于传统的模组…

stable diffusion webui mov2mov

手把手教你用stable diffusion绘画ai插件mov2mov生成动画_哔哩哔哩_bilibili手把手教你用stable diffusion绘画ai插件mov2mov生成动画, 视频播放量 14552、弹幕量 3、点赞数 275、投硬币枚数 114、收藏人数 980、转发人数 75, 视频作者 懂你的冷兮, 作者简介 科技改变世界&…

oc基本控件2

// // ViewController.m // OcDemoTest // // Created by Mac on 2023/7/14. //#import "ViewController.h"interface ViewController () // label property (weak, nonatomic) IBOutlet UIImageView *imageView; // Use of undeclared identifier // 全局propert…

uniapp 土法 瀑布流 - vue3

效果图 代码 <template><view><!-- 瀑布流展示 --><!-- 标签页 --><view class="rowStart flexNoLineBreaking paddingCol10 innerDomPaddingRow5 tinyShadow marginBottom10"><view @click="tabsCurrent = 0; run_waterfa…