flutter(四)底部tabbar,顶部切换,页面跳转
上篇文章为大家讲述了flutter的组件;(动态组件和静态组件)本篇文章接着上篇内容继续为大家介绍flutter的其他主要组件(底部选项卡,顶部切换等等实用组件),本文针对功能点做特殊实例讲解,特别详细的整体使用我们会在其它的文章中来展开说明。每篇文章只要有代码说明 就会有demo提供。
一、底部tabbar
app开发,常见的首页框架就是 底部功能切换(Tabbar),tabbar作为主功能页面,展示给用户更多的切换功能,
- 创建主页调用类,因为里面有动态布局所以继承 StatefulWidget ,
class MyXQClient extends StatefulWidget { @override State<StatefulWidget> createState() => MyXQClientState();//调用指向MyXQClientState类 }
- 变量的定义
final appBarTitles = ['星球', '动态', '发现', '我的'];//底部切换功能数组 final tabTextStyleSelected = TextStyle(color: const Color(0xff3B9AFF));//选线卡选中字体颜色 final tabTextStyleNormal = TextStyle(color: const Color(0xff969696));//选项卡未选中字体颜色 Color themeColor = ThemeColorUtils.currentColorTheme;//设置主题标题背景颜色 int _tabIndex = 0;//选项卡下标 var tabImages;//选项卡选项图片 var _body;// var pages;
- 选项卡图片的样式设置
Image getTabImage(path) { return Image.asset(path, width: 20.0, height: 20.0); }
扫描二维码关注公众号,回复: 8493322 查看本文章 - 初始化选项卡,设置选项卡的每一个选项页面,初始化每一个页面的默认图片和选中图片
@override void initState() { super.initState(); pages = <Widget>[HomeListPage(), dongtai(), HomeListPage(), HomeListPage()]; if (tabImages == null) { tabImages = [ [ getTabImage('images/ic_nav_news_normal.png'), getTabImage('images/ic_nav_news_actived.png') ], [ getTabImage('images/ic_nav_tweet_normal.png'), getTabImage('images/ic_nav_tweet_actived.png') ], [ getTabImage('images/ic_nav_discover_normal.png'), getTabImage('images/ic_nav_discover_actived.png') ], [ getTabImage('images/ic_nav_my_normal.png'), getTabImage('images/ic_nav_my_pressed.png') ] ]; } }
- 设置选中和未选中 文本的颜色
TextStyle getTabTextStyle(int curIndex) {//设置tabbar 选中和未选中的状态文本 if (curIndex == _tabIndex) { return tabTextStyleSelected; } return tabTextStyleNormal; }
- 选项卡图片的设置
Image getTabIcon(int curIndex) {//设置tabbar选中和未选中的状态图标 if (curIndex == _tabIndex) { return tabImages[curIndex][1]; } return tabImages[curIndex][0]; }
- 切换底部选项卡,标题的变化设置
Text getTabTitle(int curIndex) { return Text(appBarTitles[curIndex], style: getTabTextStyle(curIndex)); }
- 选项卡主题设置和布局结构设置
@override Widget build(BuildContext context) { _body = IndexedStack( children: pages, index: _tabIndex, ); return MaterialApp( theme: ThemeData( primaryColor: themeColor ), home: Scaffold(//布局结构 appBar: AppBar(//选中每一项的标题和图标设置 title: Text(appBarTitles[_tabIndex], style: TextStyle(color: Colors.white)), iconTheme: IconThemeData(color: Colors.white) ), body: _body, bottomNavigationBar: CupertinoTabBar(// items: <BottomNavigationBarItem>[ BottomNavigationBarItem( icon: getTabIcon(0), title: getTabTitle(0)), BottomNavigationBarItem( icon: getTabIcon(1), title: getTabTitle(1)), BottomNavigationBarItem( icon: getTabIcon(2), title: getTabTitle(2)), BottomNavigationBarItem( icon: getTabIcon(3), title: getTabTitle(3)), ], currentIndex: _tabIndex, onTap: (index) { setState((){ _tabIndex = index; }); }, ), // drawer: MyDrawer() ), ); }
二、图片资源加载
上一步我们实现了选项卡切换,同时需要加载图片,但是图片资源怎么加载呢,目录如何读取呢?
- 图片资源目录创建,
在项目根目录下创建一个文件(images),名称可以自己定义,目录结构可以自己定义,所以需要用到的资源图片存放在该目录。 - 图片目录读取
读取图片需要按照创建目录层次读取 - 声明资源
图片资源需要在pubspec.yaml
文件中声明资源,它将会打包到响应的package中。包本身使用的资源必须在pubspec.yaml
中指定。
三、库文件引用
在开发中会用到外部资源库文件的引用,比如网络调用,可以使用库文件
在使用中需要在pubspec.yaml中声明引用,加载时需要点击 packages get 等待加载成功后使用
点击packages get 后加载中
四、顶部功能切换
顶部切换功能,用于做模块分类,通过Scaffold ;布局结构实现,设置DefaultTabController 来设置切换的个数(length)和切换的child
@override
Widget build(BuildContext context) {
return Scaffold(
body: DefaultTabController(
length: 2,
child: Scaffold(
appBar: TabBar(
labelColor: Colors.black,//字体颜色
tabs: <Widget>[//选项卡内容
Tab(
text: "星球动态",
),
Tab(
text: "与我相关",
)
],
),
body: TabBarView(//选项卡 切换的内容信息展示和调用
children: <Widget>[
getRecBody(),
getLatestBody(),
],
)),
),
);
}
五、页面跳转
- 异步跳转,可以在结果中处理操作
onTap: () async { final result = await Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) { return LoginPage(); })); if (result != null && result == "refresh") {//做一些进入处理操作,比如加载效果 // Constants.eventBus.fire(LoginEvent()); } },
- 同步跳转,直接进入跳转的页面
Navigator.of(context).push(MaterialPageRoute( builder: (ctx) { // return MainPage(); } ));
六、数据传递
- 数据传递
页面跳转中往往需要带一些参数或者数据,要求传递数据
(1)跳转页面带数据(title)
(2)接受数据并传递,显示onTap: () async { final result = await Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) { return LoginPage(title:"我是从上一层带过来的数据:小蜗"); })); if (result != null && result == "refresh") {//做一些进入处理操作,比如加载效果 // Constants.eventBus.fire(LoginEvent()); } },
class LoginPage extends StatefulWidget { final String title; LoginPage({Key key, this.title});//接收数据 @override createState() => new LoginPageState(title: this.title);//传递数据使用 }
class LoginPageState extends State<LoginPage> { String title; LoginPageState({Key key,this.title}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(//标题bar title: Text("登录", style: TextStyle(color: Colors.white)),//标题和颜色 iconTheme: IconThemeData(color: Colors.white),//返回键和颜色 ), body: Container( padding: const EdgeInsets.all(10.0), child: Column( children: <Widget>[ Center(child: Text("欢迎进入星球")), Center(child: Text(title)), ], ), ) ); } }
七、总结
本章重点掌握,库加载声明和图片资源声明,在页面跳转的时候使用传递更多的类型。
完整代码地址: https://github.com/chenjianpeng/flutter/tree/master/flutter_demo002
-END-
程序职场
一个执着的职场程序员