如何解决如何在Flutter中从另一个页面调用选项卡控制器
我有带有4个选项卡的底部导航栏,并且都可以正常工作,但是我还有一个类名为BannerImageItem,我想从那里调用选项卡2。我尝试使用Gloabal键,但从Tab控制器获取null时请帮助我,我被卡住了。
我有带有4个选项卡的底部导航栏,并且都可以正常工作,但是我还有一个类名为BannerImageItem,我想从那里调用选项卡2。我尝试使用Gloabal键,但是从Tab控制器获取null时请帮助我,我被卡住了。
const int tabCount = 3;
const int turnsToRotateRight = 1;
const int turnsToRotateLeft = 3;
class MainTabControlDelegate {
int index;
Function(String naMetab) changeTab;
Function(int index) tabAnimateto;
static MainTabControlDelegate _instance;
static MainTabControlDelegate getInstance() {
return _instance ??= MainTabControlDelegate._();
}
MainTabControlDelegate._();
}
class MainTabs extends StatefulWidget {
MainTabs({Key key}) : super(key: key);
@override
MainTabsstate createState() => MainTabsstate();
}
class MainTabsstate extends State<MainTabs>
with
WidgetsBindingObserver,SingleTickerProviderStateMixin,AfterLayoutMixin {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final PageStorageBucket bucket = PageStorageBucket();
final StreamController<String> _controllerRouteWeb =
StreamController<String>.broadcast();
final _auth = FirebaseAuth.instance;
var tabData;
Map saveIndexTab = Map();
FirebaseUser loggedInUser;
bool isAdmin = false;
final List<Widget> _tabView = [];
TabController tabController;
@override
void afterFirstLayout(BuildContext context) {
loadTabBar(context);
}
Widget tabView(Map<String,dynamic> data) {
switch (data['layout']) {
case 'category':
return CategoriesScreen(
key: Key("category"),layout: data['categoryLayout'],categories: data['categories'],images: data['images'],showChat: data['showChat'],);
case 'search':
return SearchScreen(key: Key("search"),showChat: data['showChat']);
case 'cart':
return CartScreen(showChat: data['showChat']);
case 'profile':
return UserScreen(
settings: data['settings'],background: data['background'],showChat: data['showChat']);
case 'blog':
return HorizontalSliderList(config: data);
case 'wishlist':
return screen.WishList(canPop: false,showChat: data['showChat']);
case 'page':
return WebViewScreen(
title: data['title'],url: data['url'],showChat: data['showChat']);
case 'html':
return StaticSite(data: data['data'],showChat: data['showChat']);
case 'static':
return StaticPage(data: data['data'],showChat: data['showChat']);
case 'postScreen':
return PostScreen(
pageId: data['pageId'],pageTitle: data['pageTitle'],isLocatedInTabbar: true,showChat: data['showChat']);
case 'dynamic':
default:
return HomeScreen();
}
}
void changeTab(String naMetab) {
if (kLayoutWeb) {
_controllerRouteWeb.sink
.add(naMetab.contains("/") ? naMetab : '/$naMetab');
} else {
tabController?.animateto(saveIndexTab[naMetab] ?? 0);
}
}
void loadTabBar(context) {
tabData = Provider.of<AppModel>(context,listen: false).appConfig['TabBar']
as List;
for (var i = 0; i < tabData.length; i++) {
Map<String,dynamic> _dataOfTab = Map.from(tabData[i]);
saveIndexTab[_dataOfTab['layout']] = i;
_tabView.add(tabView(_dataOfTab));
}
setState(() {
tabController = TabController(length: _tabView.length,vsync: this);
});
if (MainTabControlDelegate.getInstance().index != null) {
tabController.animateto(MainTabControlDelegate.getInstance().index);
} else {
MainTabControlDelegate.getInstance().index = 0;
}
// Load the Design from FluxBuilder
tabController.addListener(() {
eventBus.fire('tab_${tabController.index}');
if (_tabView[tabController.index] is SearchScreen) {
eventBus.fire(UpdateSearchFilterEvent());
}
MainTabControlDelegate.getInstance().index = tabController.index;
});
}
Future<void> getCurrentUser() async {
try {
//Provider.of<usermodel>(context).getUser();
final user = await _auth.currentUser();
if (user != null) {
setState(() {
loggedInUser = user;
});
}
} catch (e) {
printLog("[tabbar] getCurrentUser error ${e.toString()}");
}
}
bool checkIsAdmin() {
if (loggedInUser.email == adminemail) {
isAdmin = true;
} else {
isAdmin = false;
}
return isAdmin;
}
@override
void initState() {
if (!kIsWeb) {
getCurrentUser();
}
MainTabControlDelegate.getInstance().changeTab = changeTab;
MainTabControlDelegate.getInstance().tabAnimateto = (int index) {
tabController?.animateto(index);
};
super.initState();
WidgetsBinding.instance.addobserver(this);
}
@override
void dispose() {
tabController?.dispose();
_controllerRouteWeb?.close();
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.paused) {
// went to Background
}
if (state == AppLifecycleState.resumed) {
// came back to Foreground
final appModel = Provider.of<AppModel>(context,listen: false);
if (appModel.deeplink?.isNotEmpty ?? false) {
if (appModel.deeplink['screen'] == 'NotificationScreen') {
appModel.deeplink = null;
Navigator.push(
context,MaterialPageRoute(builder: (context) => NotificationScreen()),);
}
}
}
super.didChangeAppLifecycleState(state);
}
@override
Widget build(BuildContext context) {
printLog('[tabbar] ============== tabbar.dart DASHBOARD ==============');
final isDesktop = isdisplayDesktop(context);
Utils.setStatusBarWhiteForeground(false);
kLayoutWeb = (kIsWeb || isDesktop);
if (_tabView.isEmpty) {
return Container(
color: Colors.white,child: kLoadingWidget(context),);
}
return renderBody(context);
}
Widget renderBody(BuildContext context) {
final ThemeData theme = Theme.of(context);
if (kLayoutWeb) {
final isDesktop = isdisplayDesktop(context);
return Scaffold(
backgroundColor: Theme.of(context).backgroundColor,body: SafeArea(
// For desktop layout we do not want to have SafeArea at the top and
// bottom to display 100% height content on the accounts view.
top: !isDesktop,bottom: !isDesktop,child: Theme(
// This theme effectively removes the default visual touch
// Feedback for tapping a tab,which is replaced with a custom
// animation.
data: theme.copyWith(
splashColor: Colors.transparent,highlightColor: Colors.transparent,),child: LayoutWebCustom(
menu: MenuBar(controllerRouteWeb: _controllerRouteWeb),content: StreamBuilder<String>(
initialData: RouteList.homeScreen,stream: _controllerRouteWeb.stream,builder: (context,snapshot) {
return Navigator(
key: Key(snapshot.data),initialRoute: snapshot.data,onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute(
builder: Routes.getRouteByName(settings.name),settings: settings,maintainState: false,fullscreenDialog: true,);
},);
},)),);
} else {
final screenSize = MediaQuery.of(context).size;
return Container(
color: Theme.of(context).backgroundColor,child: Scaffold(
backgroundColor: Theme.of(context).backgroundColor,resizetoAvoidBottomPadding: false,key: _scaffoldKey,body: WillPopScope(
onWillPop: () async {
if (tabController.index != 0) {
tabController.animateto(0);
return false;
} else {
return showDialog(
context: context,builder: (context) => AlertDialog(
title: Text(S.of(context).areYouSure),content: Text(S.of(context).doYouWantToExitApp),actions: <Widget>[
FlatButton(
onpressed: () => Navigator.of(context).pop(false),child: Text(S.of(context).no),FlatButton(
onpressed: () => Navigator.of(context).pop(true),child: Text(S.of(context).yes),],) ??
false;
}
},child: TabBarView(
controller: tabController,physics: NeverScrollableScrollPhysics(),children: _tabView,drawer: Drawer(child: MenuBar()),bottomNavigationBar: SafeArea(
top: false,child: Container(
width: screenSize.width,child: FittedBox(
child: Container(
width: screenSize.width /
(2 / (screenSize.height / screenSize.width)),child: TabBar(
controller: tabController,tabs: renderTabbar(),isScrollable: false,labelColor: Theme.of(context).primaryColor,indicatorSize: TabBarIndicatorSize.label,indicatorPadding: EdgeInsets.all(4.0),indicatorColor: Theme.of(context).primaryColor,);
}
}
List<Widget> renderTabbar() {
final isTablet = Tools.isTablet(MediaQuery.of(context));
var totalCart = Provider.of<CartModel>(context).totalCartQuantity;
final tabData = Provider.of<AppModel>(context,listen: false)
.appConfig['TabBar'] as List;
List<Widget> list = [];
tabData.forEach((item) {
var icon = !item["icon"].contains('/')
? Icon(
feathericons[item["icon"]],color: Theme.of(context).accentColor,size: 22,)
: (item["icon"].contains('http')
? Image.network(
item["icon"],width: 24,)
: Image.asset(
item["icon"],));
if (item["layout"] == "cart") {
icon = Stack(
children: <Widget>[
Container(
width: 30,height: 25,padding: const EdgeInsets.only(right: 6.0,top: 4),child: icon,if (totalCart > 0)
Positioned(
right: 0,top: 0,child: Container(
padding: const EdgeInsets.all(1),decoration: Boxdecoration(
color: Colors.red,borderRadius: BorderRadius.circular(8),constraints: BoxConstraints(
minWidth: 16,minHeight: 16,child: Text(
totalCart.toString(),style: TextStyle(
color: Colors.white,fontSize: isTablet ? 14 : 12,textAlign: TextAlign.center,)
],);
}
if (item["label"] != null) {
list.add(Tab(icon: icon,text: item["label"]));
} else {
list.add(Tab(icon: icon));
}
});
return list;
}
}
这是BannerImageItem
/// The Banner type to display the image
class BannerImageItem extends StatefulWidget {
@override
final Key key;
final dynamic config;
final double width;
final double padding;
final BoxFit BoxFit;
final double radius;
BannerImageItem({
this.key,this.config,this.padding,this.width,this.BoxFit,this.radius,}) : super(key: key);
@override
_BannerImageItemState createState() => _BannerImageItemState();
}
class _BannerImageItemState extends State<BannerImageItem>
with AfterLayoutMixin {
List<Product> _products;
GlobalKey<MainTabsstate> _scaffoldKey = GlobalKey<MainTabsstate>();
@override
void afterFirstLayout(BuildContext context) {
/// for pre-load the list product
if (widget.config['data'] != null) {
print(widget.config['data']);
_products = widget.config['data'];
}
}
@override
Widget build(BuildContext context) {
double _padding =
Tools.formatDouble(widget.config["padding"] ?? widget.padding ?? 10.0);
double _radius = Tools.formatDouble(widget.config['radius'] ??
(widget.radius != null ? widget.radius : 0.0));
final screenSize = MediaQuery.of(context).size;
final screenWidth =
screenSize.width / (2 / (screenSize.height / screenSize.width));
final itemWidth = widget.width ?? screenWidth;
return GestureDetector(key: _scaffoldKey,onTap: () { _scaffoldKey.currentState.tabController.animateto(1);
},child: Container(
width: itemWidth,child: Padding(
padding: EdgeInsets.only(left: _padding,right: _padding),child: ClipRRect(
borderRadius: BorderRadius.circular(_radius),child: Tools.image(
fit: widget.BoxFit ?? BoxFit.fitWidth,url: widget.config["image"],);
}
}
解决方法
return GestureDetector(key: _scaffoldKey,onTap: () { _scaffoldKey.currentState.tabController.animateTo(1);
},child: Container(
width: itemWidth,child: Padding(
padding: EdgeInsets.only(left: _padding,right: _padding),child: ClipRRect(
borderRadius: BorderRadius.circular(_radius),child: Tools.image(
fit: widget.boxFit ?? BoxFit.fitWidth,url: widget.config["image"],),);
替换为
return GestureDetector(
onTap: () { MainTabControlDelegate.getInstance().tabAnimateTo(1);
},);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。