假设你已经创建好项目,并集成了getx
一 使用getx
的命令行工具创建tab页面
- 创建底部tab
get create page:tabs
2. 创建tab所属的页面
也就是首页、购物车、我的,首页默认创建了,就不需要重复创建
get create page:user
当前项目架构
二 将页面与tab关联
- 因为我们其实首先进入的不是
home
,而是tabs
,所以呢,我们将路由里的所有除tabs
以外的页面都删除
将
lib\\app\\routes\\app_pages.dart
页面修改如下:
import 'package:get/get.dart';
import '../modules/tabs/bindings/tabs_binding.dart';
import '../modules/tabs/views/tabs_view.dart';
part 'app_routes.dart';
class AppPages {
AppPages._();
static const INITIAL = Routes.TABS; //注意这里要改成tabs,本来入口是home
static final routes = [
GetPage(
name: _Paths.TABS,
page: () => const TabsView(),
binding: TabsBinding(),
),
];
}
将
lib\\app\\routes\\app_routes.dart
页面修改如下:
part of 'app_pages.dart';
abstract class Routes {
Routes._();
static const TABS = _Paths.TABS;
}
abstract class _Paths {
_Paths._();
static const TABS = '/tabs';
}
这里无法理解的,可以按下图来理解
我们原本以为的:
实际上是:
- 你可能会急,但是你别急,我知道,你发现还是没有任何变化,所以呢,接下来做的就很重要了
修改
lib\app\modules\tabs\\views\\tabs_view.dart
文件
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../controllers/tabs_controller.dart';
class TabsView extends GetView<TabsController> {
const TabsView({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('TabsView'),
centerTitle: true,
),
body: const Center(
child: Text(
'TabsView is working',
style: TextStyle(fontSize: 20),
),
),
//从这开始是新增的【bottomNavigationBar】,我们先将底部的ICON和名称设置一下
//按照你的UI,将下面的内容
bottomNavigationBar: BottomNavigationBar(
fixedColor: Colors.red, //选中的颜色
currentIndex: 0, //第几个菜单选中
type: BottomNavigationBarType.fixed, //如果有4个或者4个以上的
onTap: (index) {},
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: "首页",
),
BottomNavigationBarItem(
icon: Icon(Icons.shopping_cart),
label: "购物车",
),
BottomNavigationBarItem(
icon: Icon(Icons.people),
label: "用户",
),
],
),
);
}
}
现在,你
run
一下,是不是底部的tab栏已经出现了,但是你发现,切换是没有效果的,那怎么办呢?
- 实现tab栏切换效果
修改
lib\app\modules\tabs\\controllers\\tabs_controller.dart
import 'package:get/get.dart';
class TabsController extends GetxController {
//TODO: Implement TabsController
RxInt currentIndex = 0.obs; //步骤3新增:新建一个变量,用于监听哪一个被选中
void onInit() {
super.onInit();
}
void onClose() {
super.onClose();
}
/// 步骤3新增: 更新被选中的值
void setCurrentIndex(index){
//将index赋值给currentIndex,并刷新数据
currentIndex.value = index;
update();
}
}
修改
lib\app\modules\tabs\\views\\tabs_view.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../controllers/tabs_controller.dart';
class TabsView extends GetView<TabsController> {
const TabsView({Key? key}) : super(key: key);
Widget build(BuildContext context) {
//步骤3新增:使用Obx 包裹Scaffold.用于监听数据变化
return Obx(() => Scaffold(
appBar: AppBar(
title: const Text('TabsView'),
centerTitle: true,
),
body: const Center(
child: Text(
'TabsView is working',
style: TextStyle(fontSize: 20),
),
),
bottomNavigationBar: BottomNavigationBar(
fixedColor: Colors.red,
currentIndex: controller.currentIndex.value, //步骤3新增:第几个菜单选中
type: BottomNavigationBarType.fixed, //如果有4个或者4个以上的
onTap: (index) {
//步骤3新增:将当前选中的赋值给变量
controller.setCurrentIndex(index);
},
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: "首页",
),
BottomNavigationBarItem(
icon: Icon(Icons.shopping_cart),
label: "购物车",
),
BottomNavigationBarItem(
icon: Icon(Icons.people),
label: "用户",
),
],
),
));
}
}
现在,你发现底部的tab栏可以了,但是呢,界面没有变化,
- 实现tab栏与主页面的绑定
修改
lib\app\modules\tabs\\controllers\\tabs_controller.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../cart/views/cart_view.dart';
import '../../home/views/home_view.dart';
import '../../user/views/user_view.dart';
class TabsController extends GetxController {
//TODO: Implement TabsController
RxInt currentIndex = 0.obs; //新建一个变量,用于监听哪一个被选中
//步骤4新增:将页面放在List里,切换页面就是用下标选中当前页面切换,注意,每一个页面的顺序要和底部对应
final List<Widget> pages = const [
HomeView(),
CartView(),
UserView(),
];
void onInit() {
super.onInit();
}
void onClose() {
super.onClose();
}
/// 更新被选中的值
void setCurrentIndex(index){
currentIndex.value = index;
update();
}
}
修改
lib\app\modules\tabs\\views\\tabs_view.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../controllers/tabs_controller.dart';
class TabsView extends GetView<TabsController> {
const TabsView({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Obx(() => Scaffold(
appBar: AppBar(
title: const Text('TabsView'),
centerTitle: true,
),
//步骤4新增:将Body的内容用主页面代替
body: controller.pages[controller.currentIndex.value],
bottomNavigationBar: BottomNavigationBar(
fixedColor: Colors.red,
currentIndex: controller.currentIndex.value, //第几个菜单选中
type: BottomNavigationBarType.fixed, //如果有4个或者4个以上的
onTap: (index) {
controller.setCurrentIndex(index);
},
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: "首页",
),
BottomNavigationBarItem(
icon: Icon(Icons.shopping_cart),
label: "购物车",
),
BottomNavigationBarItem(
icon: Icon(Icons.people),
label: "用户",
),
],
),
));
}
}
这个时候你发现,tab栏切换和页面是同步的,此时,基本上大部分完成了,接下来,我们修改BUG和点缀一下
三 修改BUG:为什么有两个标题栏???
这里很简单,我们要用的仅仅是主页面的
标题栏
,不需要tabs
的标题栏
,把它删了即可!
修改lib\app\modules\tabs\\views\\tabs_view.dart
return Obx(() => Scaffold(
//删除这里的appBar即可
// appBar: AppBar(
// title: const Text('TabsView'),
// centerTitle: true,
// ),
body: controller.pages[controller.currentIndex.value],
bottomNavigationBar: BottomNavigationBar(
OK。问题解决了
四 实际开发时,还需要进行的一些操作
- 将几个主页面的
controller
放在tabs_binding
进行懒加载,用于一些数据传输,状态管理等工作
修改
lib\app\modules\tabs\\bindings\\tabs_binding.dart
import 'package:get/get.dart';
import '../../cart/controllers/cart_controller.dart';
import '../../home/controllers/home_controller.dart';
import '../../user/controllers/user_controller.dart';
import '../controllers/tabs_controller.dart';
class TabsBinding extends Bindings {
void dependencies() {
Get.lazyPut<TabsController>(
() => TabsController(),
);
//在这里进行懒加载
Get.lazyPut<HomeController>(
() => HomeController(),
);
Get.lazyPut<CartController>(
() => CartController(),
);
Get.lazyPut<UserController>(
() => UserController(),
);
}
}