flutter(四)底部tabbar,顶部切换,页面跳转
上篇文章为大家讲述了flutter的组件;(动态组件和静态组件)本篇文章接着上篇内容继续为大家介绍flutter的其他主要组件(底部选项卡,顶部切换等等实用组件),本文针对功能点做特殊实例讲解,特别详细的整体使用我们会在其它的文章中来展开说明。每篇文章只要有代码说明 就会有demo提供。
前言
一、底部tabbar
二、图片资源加载
三、库文件引用
四、顶部功能切换
五、页面跳转
六、数据传递
七、总结
一、底部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);
}
- 初始化选项卡,设置选项卡的每一个选项页面,初始化每一个页面的默认图片和选中图片
@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)
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());
}
},
(2)接受数据并传递,显示
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-
程序职场
一个执着的职场程序员

|