flutter实现头部tabTop滚动栏
作者:舜岳 发布时间:2022-03-21 14:00:06
标签:flutter,tabTop,滚动栏
本文实例为大家分享了flutter实现头部tabTop滚动栏的具体代码,供大家参考,具体内容如下
效果图如下:
main.dart代码如下:
import 'package:flutter/material.dart';
//启动函数
void main() => runApp(MyApp());
//自定义组件
class MyApp extends StatelessWidget {
? @override
? Widget build(BuildContext context) {
? ? //MaterialApp 是flutter的页面根组件
? ? return MaterialApp(
? ? ? title: 'main根页面',
? ? ? debugShowCheckedModeBanner: false, ?//清除debug
? ? ? //home表示页面信息
? ? ? home: AppbarTop()
? ? );
? }
}
//头部tabTop滚动栏效果组件
import 'package:flutter/material.dart';
class AppbarTop extends StatefulWidget {
? @override
? _AppbarTopState createState() => _AppbarTopState();
}
//混合SingleTickerProviderStateMixin类 同步属性
class _AppbarTopState extends State<AppbarTop>
? ? with SingleTickerProviderStateMixin {
? //定义一个控制器
? TabController _tabController;
? @override
? void initState() {
? ? super.initState();
? ? //混入SingleTickerProviderStateMixin的this
? ? //实例化一个tab控制器 作用:
? ? _tabController = TabController(length: choices.length, vsync: this);
? }
? _nextPage(index) {
? ? int currentIndex = _tabController.index + index;
? ? if (currentIndex < -0) currentIndex = _tabController.length - 1;
? ? if (currentIndex >= _tabController.length) currentIndex = 0;
? ? //控制器移动到currentIndex处
? ? _tabController.animateTo(currentIndex);
? }
? @override
? Widget build(BuildContext context) {
? ? return Scaffold(
? ? ? appBar: AppBar(
? ? ? ? title: Text('头部菜单栏'),
? ? ? ? centerTitle: true, //title居中显示
? ? ? ? leading: IconButton(
? ? ? ? ? ? icon: Icon(Icons.arrow_back),
? ? ? ? ? ? onPressed: () {
? ? ? ? ? ? ? _nextPage(-1);
? ? ? ? ? ? }),
? ? ? ? iconTheme: IconThemeData(color: Colors.yellow), //头部icon样式颜色
? ? ? ? //右边icon图标 可以多个
? ? ? ? actions: <Widget>[
? ? ? ? ? IconButton(
? ? ? ? ? ? ? icon: Icon(Icons.arrow_forward),
? ? ? ? ? ? ? onPressed: () {
? ? ? ? ? ? ? ? _nextPage(1);
? ? ? ? ? ? ? })
? ? ? ? ],
? ? ? ? actionsIconTheme: IconThemeData(color: Colors.white),
? ? ? ? //自定义导航栏
? ? ? ? bottom: PreferredSize(
? ? ? ? ? ? child: Theme(
? ? ? ? ? ? ? data: Theme.of(context).copyWith(accentColor: Colors.white),
? ? ? ? ? ? ? child: Container(
? ? ? ? ? ? ? ? height: 40,
? ? ? ? ? ? ? ? alignment: Alignment.center, //圆点居中
? ? ? ? ? ? ? ? //给自定义导航栏设置圆点控制器
? ? ? ? ? ? ? ? child: TabPageSelector(
? ? ? ? ? ? ? ? ? controller: _tabController,
? ? ? ? ? ? ? ? ),
? ? ? ? ? ? ? ),
? ? ? ? ? ? ),
? ? ? ? ? ? preferredSize: Size.fromHeight(48)),
? ? ? ),
? ? ? //主体内容
? ? ? body: TabBarView(
? ? ? ? //主题内容也跟随控制器变化
? ? ? ? controller: _tabController,
? ? ? ? //将数据遍历成n个子组件数组
? ? ? ? children: choices.map((item) {
? ? ? ? ? return Padding(
? ? ? ? ? ? padding: EdgeInsets.all(20),
? ? ? ? ? ? child: ChoiceCard(
? ? ? ? ? ? ? choice: item,
? ? ? ? ? ? ),
? ? ? ? ? );
? ? ? ? }).toList(),
? ? ? ),
? ? );
? }
}
//ChoiceCard将数据渲染到Card卡片组件上
class ChoiceCard extends StatelessWidget {
? final Choice choice;
? const ChoiceCard({Key key, this.choice}) : super(key: key);
? @override
? Widget build(BuildContext context) {
? ? //滚动时的卡片小部件
? ? return Card(
? ? ? color: Colors.blue,
? ? ? child: Column(
? ? ? ? mainAxisAlignment: MainAxisAlignment.center,
? ? ? ? children: <Widget>[
? ? ? ? ? Icon(choice.icon, size: 120, color: Colors.white,),
? ? ? ? ? Text(choice.title),
? ? ? ? ],
? ? ? )
? ? );
? }
}
//数据的类型
class Choice {
? const Choice({this.title, this.icon});
? final String title;
? final IconData icon;
}
//模拟的数据
const List<Choice> choices = const <Choice>[
? const Choice(title: 'CAR', icon: Icons.directions_car),
? const Choice(title: 'BICYCLE', icon: Icons.directions_bike),
? const Choice(title: 'BOAT', icon: Icons.directions_boat),
? const Choice(title: 'BUS', icon: Icons.directions_bus),
? const Choice(title: 'TRAIN', icon: Icons.directions_railway),
? const Choice(title: 'WALK', icon: Icons.directions_walk),
];
效果图2:
代码如下:
//头部tabTop滚动栏效果组件
class AppBarBottom extends StatefulWidget {
? AppBarBottom({Key key}) : super(key: key);
? @override
? _AppBarBottomState createState() => _AppBarBottomState();
}
class _AppBarBottomState extends State<AppBarBottom> {
? _SelectView(icon, text, id) {
? ? return PopupMenuItem(
? ? ? ? child: Row(
? ? ? mainAxisAlignment: MainAxisAlignment.spaceAround,
? ? ? children: <Widget>[
? ? ? ? Icon(icon, color: Colors.blue),
? ? ? ? Text(
? ? ? ? ? text,
? ? ? ? ? style: TextStyle(color: Colors.black),
? ? ? ? )
? ? ? ],
? ? ));
? }
? @override
? Widget build(BuildContext context) {
? ? //tab使用这个组件
? ? return DefaultTabController(
? ? ? ? length: choices.length,
? ? ? ? child: Scaffold(
? ? ? ? ? appBar: AppBar(
? ? ? ? ? ? title: Text('AppBar与TabBar'),
? ? ? ? ? ? centerTitle: true,
? ? ? ? ? ? actions: <Widget>[
? ? ? ? ? ? ? PopupMenuButton(
? ? ? ? ? ? ? ? ? shape: BeveledRectangleBorder(
? ? ? ? ? ? ? ? ? ? ? borderRadius: BorderRadius.circular(10)),
? ? ? ? ? ? ? ? ? itemBuilder: (BuildContext context) {
? ? ? ? ? ? ? ? ? ? return [
? ? ? ? ? ? ? ? ? ? ? PopupMenuItem(
? ? ? ? ? ? ? ? ? ? ? ? ? child: _SelectView(Icons.message, '首页', 'A')),
? ? ? ? ? ? ? ? ? ? ? PopupMenuItem(
? ? ? ? ? ? ? ? ? ? ? ? ? child: _SelectView(Icons.message, '商品', 'B')),
? ? ? ? ? ? ? ? ? ? ? PopupMenuItem(
? ? ? ? ? ? ? ? ? ? ? ? ? child: _SelectView(Icons.message, '消息', 'C')),
? ? ? ? ? ? ? ? ? ? ];
? ? ? ? ? ? ? ? ? })
? ? ? ? ? ? ],
? ? ? ? ? ? bottom: TabBar(
? ? ? ? ? ? ? isScrollable: true,
? ? ? ? ? ? ? indicatorSize: TabBarIndicatorSize.label,
? ? ? ? ? ? ? tabs: choices.map((item) {
? ? ? ? ? ? ? ? return Tab(
? ? ? ? ? ? ? ? ? text: item.title,
? ? ? ? ? ? ? ? ? icon: Icon(item.icon),
? ? ? ? ? ? ? ? );
? ? ? ? ? ? ? }).toList(),
? ? ? ? ? ? ),
? ? ? ? ? ),
? ? ? ? ? body: TabBarView(
? ? ? ? ? ? children: choices.map((item) {
? ? ? ? ? ? ? return Container(
? ? ? ? ? ? ? ? width: double.infinity,
? ? ? ? ? ? ? ? color: Colors.white70,
? ? ? ? ? ? ? ? child: Padding(
? ? ? ? ? ? ? ? ? padding: EdgeInsets.all(16),
? ? ? ? ? ? ? ? ? child: ChoiceCard(
? ? ? ? ? ? ? ? ? ? choice: item,
? ? ? ? ? ? ? ? ? ),
? ? ? ? ? ? ? ? ),
? ? ? ? ? ? ? );
? ? ? ? ? ? }).toList(),
? ? ? ? ? ),
? ? ? ? ));
? }
}
//ChoiceCard将数据渲染到Card卡片组件上
class ChoiceCard extends StatelessWidget {
? final Choice choice;
? const ChoiceCard({Key key, this.choice}) : super(key: key);
? @override
? Widget build(BuildContext context) {
? ? //滚动时的卡片小部件
? ? return Card(
? ? ? ? color: Colors.blue,
? ? ? ? child: Column(
? ? ? ? ? mainAxisAlignment: MainAxisAlignment.center,
? ? ? ? ? children: <Widget>[
? ? ? ? ? ? Icon(
? ? ? ? ? ? ? choice.icon,
? ? ? ? ? ? ? size: 120,
? ? ? ? ? ? ? color: Colors.white,
? ? ? ? ? ? ),
? ? ? ? ? ? Text(choice.title),
? ? ? ? ? ],
? ? ? ? ));
? }
}
//数据的类型
class Choice {
? const Choice({this.title, this.icon});
? final String title;
? final IconData icon;
}
//模拟的数据
const List<Choice> choices = const <Choice>[
? const Choice(title: 'CAR', icon: Icons.directions_car),
? const Choice(title: 'BICYCLE', icon: Icons.directions_bike),
? const Choice(title: 'BOAT', icon: Icons.directions_boat),
? const Choice(title: 'BUS', icon: Icons.directions_bus),
? const Choice(title: 'TRAIN', icon: Icons.directions_railway),
? const Choice(title: 'WALK', icon: Icons.directions_walk),
];
来源:https://blog.csdn.net/qq_41614928/article/details/105334809


猜你喜欢
- 绝对路径:不可改变的路径本地绝对路径:增加盘符的路径(e:/test/test.html)网络绝对路径:增加协议,IP地址,端口号的路径(h
- 1、在ActionSupport中有一个validate()方法,这个方法是验证方法,它会在execute()方法执行之前执行,所以能够起到
- 后台管理页面往往需要登录才可以进行操作,这时就需要Seession来记录登录状态要实现起来也是非常简单,只需要自定义一个HandlerInt
- 在java中,static是一个修饰符,用于修饰类的成员方法、类的成员变量,另外可以编写static代码块来优化程序性能;被static关键
- < drawable name="white">#FFFFFF< /drawable><
- 动态数据源在很多具体应用场景的时候,我们需要用到动态数据源的情况,比如多租户的场景,系统登录时需要根据用户信息切换到用户对应的数据库。又比如
- 冒泡排序在八大排序中,冒泡排序是最为出名的排序算法之一!冒泡排序的代码还是相当简单的,两层循环,外层是冒泡轮数,里层是依次比较,这个算法的时
- 一、效果图 二、实现思路1.界面上可以点开的各种实际都是按钮,创建9行9列的二维数组,然后
- 本文实例为大家分享了java动态模拟时钟的具体代码,供大家参考,具体内容如下应用名称:java动态模拟时钟用到的知识:javaGUI,jav
- 先看一段同步代码:public int SumPageSizes(IList<Uri> uris) {
- 前言自 Java 7 以来,java 中的 switch 语句经历了快速发展。因此,在本文中,我们将通过示例讨论 switch 语句从 ja
- @Autowired注解在抽象类中失效最近在工作中遇到这个问题,在抽象类中使用Autowired这个注解,注入mybatis的dao时,总是
- 这几天面试中有遇到关于main数组中的args数组传值的问题,一般是从命令提示符中传值,也可以直接在java代码中赋值。而且这个数组的长度是
- 相信绝大多数.NET玩家和我一样,常常使用Timer这个对象,而在WPF中使用DispatcherTimer的人也是很多,Dispatche
- 目录一、野指针二、悬空指针2.1 情况一2.2 情况二2.3 情况三野指针和悬空指针是指针中常见的两个概念,本文结合实例讲解来讲解下。一、野
- 概念IO流可以初步的理解为数据间的传输,我们将一组数据入:1234567,将他们从hello文件中转入haha文件中,使用程序的方法进行转入
- 前言比较运算符用于判断两个数据的大小,例如:大于、等于、不等于。比较的结果是一个布尔值( true 或 false )。Java 中常用的比
- JDK JRE JVMJDK:Java标准开发包,它提供了编译、运行Java程序所需的各种工具和资源,包括Java编译器、Java运行时环境
- SSM Mapper查询出返回数据查不到个别字段原因开启了驼峰命名法则,Bean里的字段不识别_注释掉或者把实体类里的字段_去掉换位大写SS
- 什么是SkyWalking查看官网https://skywalking.apache.org/分布式系统的应用程序性能监视工具,专为微服务、