将底部TabBar添加到AppBar(Flutter)时,TabBar没有TabController



所以我想做的是,除了我的应用程序栏中有徽标和搜索选项外,我还想添加底部的选项卡栏,用户可以在其中一个选项卡栏中选择电影或电视节目,当他在其中之一时,文本应该亮起(不同的颜色(。但当我尝试添加TabBar时,我遇到了一个错误:

══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following assertion was thrown building MediaQuery(MediaQueryData(size: Size(411.4, 683.4),
devicePixelRatio: 2.6, textScaleFactor: 1.0, platformBrightness: Brightness.light, padding:
EdgeInsets.zero, viewPadding: EdgeInsets.zero, viewInsets: EdgeInsets.zero, alwaysUse24HourFormat:
false, accessibleNavigation: false, highContrast: false, disableAnimations: false, invertColors:
false, boldText: false, navigationMode: traditional)):
No TabController for TabBar.
When creating a TabBar, you must either provide an explicit TabController using the "controller"
property, or you must ensure that there is a DefaultTabController above the TabBar.
In this case, there was neither an explicit controller nor a default controller.
The relevant error-causing widget was:
AppBar file:///C:/Users/Meliha/Desktop/Rubicon/chillax/lib/presenter/home_page_movies.dart:22:15
When the exception was thrown, this was the stack:
#0      _TabBarState._updateTabController.<anonymous closure> (package:flutter/src/material/tabs.dart:965:9)
#1      _TabBarState._updateTabController (package:flutter/src/material/tabs.dart:974:6)
#2      _TabBarState.didChangeDependencies (package:flutter/src/material/tabs.dart:1006:5)
#3      StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4653:11)
#4      ComponentElement.mount (package:flutter/src/widgets/framework.dart:4469:5)
#5      Element.inflateWidget (package:flutter/src/widgets/framework.dart:3541:14)
#6      MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6094:32)
...     Normal element mounting (99 frames)
#105    Element.inflateWidget (package:flutter/src/widgets/framework.dart:3541:14)
#106    MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6094:32)
...     Normal element mounting (238 frames)
#344    Element.inflateWidget (package:flutter/src/widgets/framework.dart:3541:14)
#345    MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6094:32)
...     Normal element mounting (300 frames)
#645    Element.inflateWidget (package:flutter/src/widgets/framework.dart:3541:14)
#646    Element.updateChild (package:flutter/src/widgets/framework.dart:3306:18)
#647    RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:1182:16)
#648    RenderObjectToWidgetElement.mount (package:flutter/src/widgets/binding.dart:1153:5)
#649    RenderObjectToWidgetAdapter.attachToRenderTree.<anonymous closure> (package:flutter/src/widgets/binding.dart:1095:18)
#650    BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2647:19)
#651    RenderObjectToWidgetAdapter.attachToRenderTree (package:flutter/src/widgets/binding.dart:1094:13)
#652    WidgetsBinding.attachRootWidget (package:flutter/src/widgets/binding.dart:934:7)
#653    WidgetsBinding.scheduleAttachRootWidget.<anonymous closure> (package:flutter/src/widgets/binding.dart:915:7)
(elided 11 frames from class _RawReceivePortImpl, class _Timer, dart:async, and dart:async-patch)
════════════════════════════════════════════════════════════════════════════════════════════════════

这是电影主页的代码:

import 'package:eva_icons_flutter/eva_icons_flutter.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:movie_app/view/now_playing_movie.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:movie_app/view/now_playing_tv.dart';
import 'package:movie_app/view/test.dart';
import 'package:movie_app/view/top_movies.dart';
import 'package:movie_app/view/top_tvs.dart';
import '../style/style.dart';
class HomePageMovie extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePageMovie> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFF151C26),
appBar: AppBar(
backgroundColor: Color(0xFF151C26),
title: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SvgPicture.asset(
logo,
height: 195,
),
],
),
actions: <Widget>[
IconButton(
onPressed: () {},
icon: Icon(
EvaIcons.searchOutline,
color: Colors.white,
))
],
bottom: TabBar(
indicatorColor: Color(0xFFf4C10F),
indicatorSize: TabBarIndicatorSize.tab,
indicatorWeight: 3.0,
unselectedLabelColor: Colors.white,
labelColor: Colors.white,
isScrollable: true,
tabs: [
Tab(
icon: Icon(Icons.movie),
text: "Movies",
),
Tab(
icon: Icon(Icons.tv),
text: "TV Shows",
)
]),
titleSpacing: 0.0,
),
body: ListView(
children: <Widget>[
NowPlayingMovies(),
BestMovie(),
],
),
);
}
}

任何形式的帮助/提示/指导都会很棒。提前感谢

问题的解决方案就在错误文本中

创建TabBar时,必须使用;控制器";属性,或者必须确保TabBar上方有一个DefaultTabController。

因此,最简单的解决方案是用DefaultTabController包装TabBar。由于您正在使用AppBarbottom属性,该属性期望PreferredSizeWidget,因此您还需要将其全部封装在实现该属性的东西中(因为它是一个抽象类(-这里最简单的解决方案就是只使用PreferredSize。完整的示例可能如下所示:

AppBar(
bottom: PreferredSize(
// Set whatever size you want - this is a good default one
preferredSize: Size.fromHeight(kToolbarHeight),
child: DefaultTabController(
length: 2,
child: TabBar(
tabs: [
Tab(
text: 'Movies',
),
Tab(
text: 'TV Shows',
),
],
),
),
),
),

错误日志有时非常详细,但这是关键消息:

创建TabBar时,必须使用;控制器";属性,或者必须确保TabBar上方有一个DefaultTabController。在这种情况下,既没有显式控制器,也没有默认控制器。

您只需要将Scaffold小部件包装在DefaultTabController中,并为其指定与选项卡数量相对应的长度。对于更复杂的行为,您可以初始化ScrollController,并将其添加到TabBarTabBarViewcontroller:参数中。

我还注意到,在该示例中,您有一个ListView,其中包含两个选项卡小部件。这行不通,把它换成TabBarView

最新更新