在上一篇里总结AppBar的一些简单用法,但是AppBar除了有前面那些样式属性外,还能实现类似底部的Tab切换。

首先下载并运行前面的项目:

然后在此基础上实现Tab切换。

常见属性

TabBar有一下常见的属性:

  • tabs :显示的标签内容,一般使用 Tab 对象,也可以是其他的 Widget
  • controller :TabController 对象
  • isScrollable :是否可滚动
  • indicatorColor :指示器颜色
  • indicatorWeight :指示器高度
  • indicatorPadding :底部指示器的 Padding
  • indicator :指示器 decoration,例如边框等
  • indicatorSize :指示器大小计算方式,TabBarIndicatorSize.label 跟文字等宽,TabBarIndicatorSize.tab 跟每个 tab 等宽
  • labelColor :选中 label 颜色
  • labelStyle :选中 label 的 Style
  • labelPadding :每个 label 的 padding 值
  • unselectedLabelColor :未选中 label 颜色
  • unselectedLabelStyle :未选中 label 的 Style

基本实现

为了实现顶部的Tabs切换,首先需要在Scaffold的外层定义一个DefaultTabController组件,然后组件里面定义tab的个数,最后将TabBar定义在AppBar里面的bottom属性中。根据这些,我们来修改前面的

AppBarDemo.dart页面。
import 'package:flutter/material.dart';

class AppBarDemoPage extends StatelessWidget {
const AppBarDemoPage({Key key}) : super(key: key); @override
Widget build(BuildContext context) {
return DefaultTabController(
length:2 ,
child: Scaffold(
appBar: AppBar(
title:Text("AppBarDemoPage"),
// backgroundColor: Colors.red,
centerTitle:true,
leading: IconButton(
icon: Icon(Icons.menu),
onPressed: (){
print('menu');
},
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.search),
onPressed: (){
print('search');
},
),
IconButton(
icon: Icon(Icons.settings),
onPressed: (){
print('settings');
},
)
],
bottom: TabBar(
tabs: <Widget>[
Tab(text: "热门"),
Tab(text: "推荐")
],
),
),
body: Text('1111'),
),
);
}
}

为了简化代码,删掉前面关于AppBar的属性设置:

AppBarDemo.dart

import 'package:flutter/material.dart';

class AppBarDemoPage extends StatelessWidget {
const AppBarDemoPage({Key key}) : super(key: key); @override
Widget build(BuildContext context) {
return DefaultTabController(
length:2 ,
child: Scaffold(
appBar: AppBar(
title:Text("AppBarDemoPage"),
centerTitle:true,
bottom: TabBar(
tabs: <Widget>[
Tab(text: "热门"),
Tab(text: "推荐")
],
),
),
body: Text('1111'),
),
);
}
}

现在,只有跳转的按钮,却没有对应的页面组件,所以,还需要在body里面添加tabs切换的页面。

 

目前,是在一个新的页面添加了顶部Tabs切换,那么,如果需要在底部TabBar页面基础上添加Tabs切换,又该如何操作呢?

TabBar中添加顶部Tab切换

按照前面说的,在Scaffold的外层定义一个DefaultTabController组件,先这样修改Category.dart页面:

import 'package:flutter/material.dart';

class CategoryPage extends StatefulWidget {
CategoryPage({Key key}) : super(key: key);
_CategoryPageState createState() => _CategoryPageState();
} class _CategoryPageState extends State<CategoryPage> {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 4,
child: Scaffold(
appBar: AppBar(
bottom:TabBar(
tabs: <Widget>[
Tab(text: "热销"),
Tab(text: "推荐"),
Tab(text: "推荐"),
Tab(text: "推荐")
],
) ,
),
body:TabBarView(
children: <Widget>[
ListView(
children: <Widget>[
ListTile(title:Text("第一个tab")),
],
),
ListView(
children: <Widget>[
ListTile(title:Text("第二个tab")),
],
),
ListView(
children: <Widget>[
ListTile(title:Text("第三个tab")),
],
),
ListView(
children: <Widget>[
ListTile(title:Text("第四个tab")),
],
)
],
)
),
);
}
}

因为Category.dart是挂载到Tabs.dart中的,而在Tabs.dart中,已经有一个Scaffold组件和AppBar组件了,所以,继续添加顶部Tabs以后,就会有两个Scaffold组件和AppBar组件。

 

为了解决上面的问题,只需要将Tabs切换换个位置,移动到title所在的位置就可以了:

import 'package:flutter/material.dart';

class CategoryPage extends StatefulWidget {
CategoryPage({Key key}) : super(key: key); _CategoryPageState createState() => _CategoryPageState();
} class _CategoryPageState extends State<CategoryPage> {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 4,
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.black26,
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child:TabBar(
            isScrollable: true, //多个Tab的时候,可以实现滑动和联动
                  indicatorColor:Colors.blue,
labelColor:Colors.blue,
unselectedLabelColor: Colors.white,
indicatorSize:TabBarIndicatorSize.label ,
tabs: <Widget>[
Tab(text: "热销"),
Tab(text: "推荐"),
Tab(text: "推荐"),
Tab(text: "推荐")
],
) ,
)
],
), ),
body:TabBarView(
children: <Widget>[
ListView(
children: <Widget>[
ListTile(title:Text("第一个tab")),
],
),
ListView(
children: <Widget>[
ListTile(title:Text("第二个tab")),
],
),
ListView(
children: <Widget>[
ListTile(title:Text("第三个tab")),
],
),
ListView(
children: <Widget>[
ListTile(title:Text("第四个tab")),
],
)
],
)
),
);
}
}

 

AppBar中自定义顶部导航的更多相关文章

  1. Flutter AppBar 自定义顶部导航按钮 图标、颜色 以及 TabBar 定义顶部 Tab 切换

    Flutter AppBar 自定义顶部按钮图 标.颜色 属性 描述 leading 在标题前面显示的一个控件,在首页通常显示应用 的 logo;在其他界面通常显示为返回按钮 title 标题,通常显 ...

  2. AppBar 自定义顶部导航按钮 图标、颜色 以及 TabBar 定义顶部 Tab 切换

    一.Flutter AppBar 自定义顶部按钮图标.颜色 leading   在标题前面显示的一个控件,在首页通常显示应用的 logo:在其他界面通常显示为返回按钮 title  标题,通常显示为当 ...

  3. 微信小程序自定义顶部导航

    注释:自定义导航需要自备相应图片 一.设置自定义顶部导航 Navigation是小程序的顶部导航组件,当页面配置navigationStyle设置为custom的时候可以使用此组件替代原生导航栏. 1 ...

  4. Flutter——AppBar组件(顶部导航组件)

    AppBar组件的常用属性如下: 属性 描述 leading 在标题前面显示的一个控件,在首页通常显示应用的 logo:在其他界面通常显示为返回按钮 title 标题,通常显示为当前界面的标题文字,可 ...

  5. ionic3.0 中带顶部导航的下拉刷新列表的实现

    1.最终实现效果 2.html代码布局: 3.css样式控制(注:下面这两个css类名需在浏览器解析后才可看到)

  6. [置顶] xamarin Tablayout+Viewpager+Fragment顶部导航栏

    最近几天不忙,所以把项目中的顶部导航栏的实现归集一下.android中使用TabLayout+ViewPager+Fragment制作顶部导航非常常见,代码实现也比较简单.当然我这个导航栏是基于xam ...

  7. yii2顶部导航使用

    yii2中使用顶部导航的具体方法: 1.视图中调用两个类: use yii\bootstrap\Nav;use yii\bootstrap\NavBar; 2. <?php            ...

  8. uni-app自定义导航栏按钮|uniapp仿微信顶部导航条

    最近一直在学习uni-app开发,由于uniapp是基于vue.js技术开发的,只要你熟悉vue,基本上很快就能上手了. 在开发中发现uni-app原生导航栏也能实现一些顶部自定义按钮+搜索框,只需在 ...

  9. TabTopLayout【自定义顶部选项卡区域(固定宽度且居中)】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 自定义顶部选项卡并居中显示.结合显示/隐藏view的方式实现切换功能(正常情况下可能是切换fragment). 效果图 代码分析 T ...

随机推荐

  1. 关于ES6语法的 一些新的特性

    1.新的变量声明 :let :块级作用域,解决全局污染问题 const :常量 ,如π:3.1415927 class :类 .var:弱类型  funciton :方法 , import : 导入参 ...

  2. Tesseract5.0训练字库,提高OCR特殊场景识别率(一)

    0.目标 很多特殊场景,原生的字库识别率不高,这时候就需要根据需求自己训练字库生成traineddata文件. 一.前期准备工作 1.安装jdk   用于运行jTessBoxEditor 2.安装jT ...

  3. Sentinel整合Dubbo限流实战(分布式限流)

    之前我们了解了 Sentinel 集成 SpringBoot实现限流,也探讨了Sentinel的限流基本原理,那么接下去我们来学习一下Sentinel整合Dubbo及 Nacos 实现动态数据源的限流 ...

  4. 时间、金钱在java、数据库中的变量类型之总结

    在编写程序时,总是有些变量的类型搞不很明白,现将目前涉及到的变量总结一下: 1.“时间”类型 (1).在数据库中的变量类型是:DateTime 比如: operateTime DATETIME,//数 ...

  5. HDFS数据流——读数据流程

    HDFS读数据流程 假设客户端请求下载文件/user/atguigu/ss.avi,HDFS读数据流程如下: 1)客户端向namenode请求下载文件,namenode通过查询元数据,找到文件所有文件 ...

  6. 极*Java速成教程 - (3)

    Java语言基础 访问权限控制 Java是一个面向对象的语言,当你不是它所设计的要面向的对象时,它就不会给你看你不该看到的东西,也就是"访问权限控制". 亲疏有别,才能权限控制 包 ...

  7. Qt之UI文件设计和运行机制

    1.项目文件组成在QtCreator中新建一个WidgetApplocation项目,选中窗口基类中选中QWidget作为窗口基类,并选中"GnerateForm"复选框.创建后项 ...

  8. AcWing 831. KMP字符串(模板)

    给定一个模式串S,以及一个模板串P,所有字符串中只包含大小写英文字母以及阿拉伯数字. 模板串P在模式串S中多次作为子串出现. 求出模板串P在模式串S中所有出现的位置的起始下标. 输入格式 第一行输入整 ...

  9. HDUSTOJ-1558 Flooring Tiles(反素数)

    1558: Flooring Tiles 时间限制: 3 Sec  内存限制: 128 MB提交: 59  解决: 36[提交][状态][讨论版] 题目描述 You want to decorate ...

  10. java synchronized实现可见性对比volatile

    问题: 大家可以先看看这个问题,看看这个是否有问题呢? 那里有问题呢? public class ThreadSafeCache { int result; public int getResult( ...