iOS开发Flutter探索-构建Tabbar结构页面(4)
前言
Tabbar结构的APP非常的常见,通常我们在iOS开发中,构建这类结构的页面会涉及到UITabbarController
,UINavigationController
,UIViewController
等组合来实现,当然了我们也可以通过自定义Tabbar
来达到页面效果。今天就给大家介绍一下在flutter中,实现Tabbar结构的方式。先看下效果图:
Scaffold
在我的理解中Scaffold
是类似于ViewController
的部件,而且它把在iOS中UITabbarController
和UINavigationController
通过属性的方式都融合在了一起。比如我们给一个Scaffold
设置了AppBar
(UINavigationBar),它就类似于iOS下的UINavigationController
的特征;当设置了bottomNavigationBar
(UITabbar)属性,就具备了UITabbarController
的特性;还有一个就是body
属性,非常类似于我们ViewController.view
。
(在flutter下,UI布局的组合非常灵活,而且实现起来也非常的简单)。
页面目录结构
zezefamily创建的目录结构.pngroot_page
里面可以理解为那个 tabbarController
pages
是tabar 指向的具体页面,或者说是viewControllers
我们还是从main.dart
开始
直接上代码了,没太多的解释,需要解释的地方,我会在代码里面标注。
import 'package:flutter/material.dart';
import 'package:flutterappzeze/root_page/root_page.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.green,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: RootPage(),
);
}
}
关于main.dart
我在做开始的文章中就有介绍(main.dart),这里其实就做了一件事,就是将home
(rootViewController)设置为RootPage()
(root_page.dart
)。
看下root_page.dart
import 'package:flutter/material.dart';
import 'package:flutterappzeze/pages/exam_page.dart';
import 'package:flutterappzeze/pages/pend_course.dart';
import 'package:flutterappzeze/pages/personal_page.dart';
import 'package:flutterappzeze/pages/taken_course.dart';
class RootPage extends StatefulWidget {
@override
_RootPageState createState() => _RootPageState();
}
class _RootPageState extends State<RootPage> {
int _currentIndex = 0; //当前索引
// ViewControllers 自定义的widget对象
List <Widget> _viewControllers = [
PendCourse(), //待上课程
TakenCourse(), //已上课程
ExamPage(), //水平测试
PersonalPage(), //我
];
// tabBarItems 看变量的命名tabbarItems,应该就知道是什么了
List <BottomNavigationBarItem> _tabBarItems = [
BottomNavigationBarItem(
icon: Icon(Icons.access_alarm), //上图
title: Text('待上课程') //下文
),
BottomNavigationBarItem(
icon: Icon(Icons.history),
title: Text('已上课程')
),
BottomNavigationBarItem(
icon: Icon(Icons.perm_camera_mic),
title: Text('水平测试')
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text('我')
),
];
@override
Widget build(BuildContext context) {
return Container(
child: Scaffold(
bottomNavigationBar: BottomNavigationBar( //ios 的 tabbar
onTap: (int index){ //tabbar点击回调,返回当前点击的索引
_currentIndex = index;
setState(() {});
},
type:BottomNavigationBarType.fixed, //tabbar点击风格
fixedColor: Colors.green, //被点击后的颜色
currentIndex: _currentIndex, //当前点击的是哪个
items: _tabBarItems, //类似于ios的TabbarItem,这里需要一个[List]
//*毕竟item是有多个,只不过这里的item 类型是BottomNavigationBarItem
//*ios下其实就是我们的UITabbarItem
),
body: _viewControllers[_currentIndex], //viewControllers,
//*当触发onTap,根据_currentIndex 来动态切换,我把他们放在了一个List
),
);
}
}
这里我们创建的widget是一个StatefulWidget
类型,因为这里我们需要通过触发onTap:
后修改索引来动态的修改body
部分的内容。关于StatelessWidget
和StatefulWidget
的介绍,请点击这里。
接下来看下pages
文件夹
这里面的4个dart 文件的内容都是一致的,这也是我们在之后的开发中具体要实现的部分。他们都是StatefulWidget
类型。我们就拿pend_course.dart
看下
// 待上课程
import 'package:flutter/material.dart';
class PendCourse extends StatefulWidget {
@override
_PendCourseState createState() => _PendCourseState();
}
class _PendCourseState extends State<PendCourse> {
@override
Widget build(BuildContext context) {
return Scaffold( //这里还是一个Scaffold
appBar: AppBar( //navigationBar
title: Text('待上课程'), //navigationBar.title (这里其实可以出入任意widget)
// * 这里我就给了一个Text (UILabel)
),
body: Center( //self.view 部分
child: Text('泽泽1'), //UILabel 这里也是任意Widget,这里是subViews部分
),
);
}
}
总结
本篇文章并没有太多的概念,就是通过代码看下在flutter中tabbar结构页面的实现,在flutter的UI层,各种widget的组合还是非常灵活的,再配合上Hod reload,效率真是杠杠的!不得不赞一个。