我正在使用AnimatedContainer,以便其高度可以(带有动画)适应其中显示的Tab的内容。我应该可以使用DefaultTabController.of(context).index访问该选项卡的当前索引,并将该数据传输到一个函数,该函数将根据当前选项卡来重建小部件。
运行代码时,它向我显示错误,但我不明白:这是否意味着DefaultTabController返回null?
这是代码:
import 'package:flutter/material.dart';
import 'package:travel_agent_app/loginForm.dart';
import 'package:travel_agent_app/registerForm.dart';
import 'package:travel_agent_app/bubble_tab_indicator.dart';
class Login extends StatefulWidget {
const Login({Key key}) : super(key: key);
_LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
double _containerHeight = 300;
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
body: Container(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
SizedBox(
height: 150,
),
Container(
padding: EdgeInsets.only(left: 20.0, right:20.0),
child: Column(
children: <Widget>[
Container(
height: 52.0,
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.all(Radius.circular(100.0))
),
child: TabBar(
indicatorSize: TabBarIndicatorSize.tab,
indicator: new BubbleTabIndicator(
indicatorHeight: 45.0,
indicatorColor: Colors.blueAccent,
tabBarIndicatorSize: TabBarIndicatorSize.tab),
labelColor: Colors.white,
unselectedLabelColor: Colors.black,
onTap: setAnimatedContainerHeight(DefaultTabController.of(context).index),
tabs: <Widget>[
Tab(text: 'Login'),
Tab(text: 'Register'),
],
),
),
SizedBox(
height: 20.0,
),
AnimatedContainer(
duration: Duration(seconds: 1),
padding: EdgeInsets.all(40.0),
width: double.infinity,
height: _containerHeight,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8.0),
boxShadow: [
BoxShadow(
color: Colors.black12,
offset: Offset(0.0, 15.0),
blurRadius: 15.0),
]),
child: TabBarView(
children: <Widget>[
Container(
width: 500.0,
child: LoginForm(),
),
RegisterForm(),
],
)
),
],
),
)
],
),
)
)
)
);
}
setAnimatedContainerHeight(int index){
if(index == 0){
setState(() {
_containerHeight = 300;
});
}
else{
setState(() {
_containerHeight = 450;
});
}
}
}
答案 0 :(得分:1)
这里的问题是DefaultTabController
上下文与定义DefaultTabController.of(context).index
的上下文相同。
要解决该错误-您需要在父上下文中定义DefaultTabController
。
您的代码有效:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: DefaultTabController( // Add here
child: Login(),
length: 2,
),
);
}
}
class Login extends StatefulWidget {
const Login({Key key}) : super(key: key);
_LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
double _containerHeight = 300;
@override
Widget build(BuildContext context) {
return Scaffold( // Remove from here
body: Container(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
SizedBox(
height: 150,
),
Container(
padding: EdgeInsets.only(left: 20.0, right: 20.0),
child: Column(
children: <Widget>[
Container(
height: 52.0,
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.all(Radius.circular(100.0))),
child: TabBar(
indicatorSize: TabBarIndicatorSize.tab,
indicator: new BubbleTabIndicator(
indicatorHeight: 45.0,
indicatorColor: Colors.blueAccent,
tabBarIndicatorSize: TabBarIndicatorSize.tab),
labelColor: Colors.white,
unselectedLabelColor: Colors.black,
onTap: setAnimatedContainerHeight(
DefaultTabController.of(context).index),
tabs: <Widget>[
Tab(text: 'Login'),
Tab(text: 'Register'),
],
),
),
SizedBox(
height: 20.0,
),
AnimatedContainer(
duration: Duration(seconds: 1),
padding: EdgeInsets.all(40.0),
width: double.infinity,
height: _containerHeight,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8.0),
boxShadow: [
BoxShadow(
color: Colors.black12,
offset: Offset(0.0, 15.0),
blurRadius: 15.0),
]),
child: TabBarView(
children: <Widget>[
Container(
width: 500.0,
child: LoginForm(),
),
RegisterForm(),
],
)),
],
),
)
],
),
)));
}
setAnimatedContainerHeight(int index) {
if (index == 0) {
setState(() {
_containerHeight = 300;
});
} else {
setState(() {
_containerHeight = 450;
});
}
}
}
答案 1 :(得分:0)
或者使用FutureBuilder
:
import 'package:flutter/material.dart';
import 'package:travel_agent_app/loginForm.dart';
import 'package:travel_agent_app/registerForm.dart';
import 'package:travel_agent_app/bubble_tab_indicator.dart';
class Login extends StatefulWidget {
const Login({Key key}) : super(key: key);
_LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
double _containerHeight = 300;
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: FutureBuilder(
future: Future.delayed(Duration.zero),
builder: (BuildContext context, AsyncSnapshot snapshot) {
return Scaffold(
// ...
// The context within here is from FutureBuilder, which include DefaultTabController
// ...
);
},
),
);
}
setAnimatedContainerHeight(int index) {
if (index == 0) {
setState(() {
_containerHeight = 300;
});
} else {
setState(() {
_containerHeight = 450;
});
}
}
}