CupertinoTabView 在热重载时重置
CupertinoTabView resets on Hot Reload
我正在使用 CupertinoApp 模型开发应用程序。我正在为应用程序使用 CupertinoTabView 模型。现在在开发过程中,选项卡索引会在热重载时重置。我尝试在选项卡控制器上设置状态,但它仍然会重置。
代码:
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
CupertinoTabController _controller = CupertinoTabController();
@override
void dispose() {
_controller.dispose();
super.dispose();
}
List<Widget> tabs = [
HomeScreen(_controller),
PlaySearchScreen(),
HomeScreen(_controller),
ProfileScreen(),
];
return CupertinoTabScaffold(
controller: _controller,
tabBar: CupertinoTabBar(
items: [
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.play),
label: 'Play Tennis',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.calendar),
label: ' My Schedule',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.person),
label: 'Profile',
),
],
),
tabBuilder: (context, index) {
return CupertinoTabView(
builder: (ctx) {
return GestureDetector(
child: tabs[index],
onTap: () => setState(
() => _controller.index = index,
),
);
},
);
});
}
}
class HomeScreen extends StatefulWidget {
HomeScreen(
this.controller, {
Key key,
}) : super(key: key);
final CupertinoTabController controller;
@override
_HomeScreenState createState() => _HomeScreenState();
}
有没有办法让它不重置?
编辑
正如 @p2kr 所指出的,你在 build
函数中混淆了(因为你也有dispose
回调,其中你想在 build
函数之外定义)并且你使用 CupertinoTabScaffold
文档指出:
You must listen to the onTap callbacks and call setState with a new
currentIndex for the new selection to reflect. This can also be done
automatically by wrapping this with a CupertinoTabScaffold.
取自 here。因此,如果您不使用 CupertinoTabScaffold
,我的原始答案将适用。在您的情况下,您的 class 应该如下所示:
class _HomePageState extends State<HomePage> {
// Placing the _controller as a property of your class
// instead of a local variable inside your build method
// which would be re-instantiated on every build call -
// as in the case of hot reload
CupertinoTabController _controller = CupertinoTabController();
// Also setting the dispose function correctly outside
// of the build function
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
List<Widget> tabs = [
HomeScreen(_controller),
PlaySearchScreen(),
HomeScreen(_controller),
ProfileScreen(),
];
...
原版
CupertinoTabBar
有一个 currentIndex
属性 来维护选定的选项卡。因此,您需要在 _HomePageState
:
中添加一个额外的 属性
class _HomePageState extends State<HomePage> {
// Variable to maintain current tab index.
// Setting it to 0 (first tab) as default here
int _index = 0;
...
}
然后在实际的 CupertinoTabBar
中,我们添加设置 currentIndex
属性 并使用 onTap
回调相应地更新我们的 属性:
CupertinoTabBar(
// Setting the index
currentIndex: _index,
// Callback to update our index once a tab is clicked
onTap: (index) => setState(() => _index = index),
items: [
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.play),
label: 'Play Tennis',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.calendar),
label: ' My Schedule',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.person),
label: 'Profile',
),
],
),
我正在使用 CupertinoApp 模型开发应用程序。我正在为应用程序使用 CupertinoTabView 模型。现在在开发过程中,选项卡索引会在热重载时重置。我尝试在选项卡控制器上设置状态,但它仍然会重置。
代码:
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
CupertinoTabController _controller = CupertinoTabController();
@override
void dispose() {
_controller.dispose();
super.dispose();
}
List<Widget> tabs = [
HomeScreen(_controller),
PlaySearchScreen(),
HomeScreen(_controller),
ProfileScreen(),
];
return CupertinoTabScaffold(
controller: _controller,
tabBar: CupertinoTabBar(
items: [
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.play),
label: 'Play Tennis',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.calendar),
label: ' My Schedule',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.person),
label: 'Profile',
),
],
),
tabBuilder: (context, index) {
return CupertinoTabView(
builder: (ctx) {
return GestureDetector(
child: tabs[index],
onTap: () => setState(
() => _controller.index = index,
),
);
},
);
});
}
}
class HomeScreen extends StatefulWidget {
HomeScreen(
this.controller, {
Key key,
}) : super(key: key);
final CupertinoTabController controller;
@override
_HomeScreenState createState() => _HomeScreenState();
}
有没有办法让它不重置?
编辑
正如 @p2kr 所指出的,你在 build
函数中混淆了(因为你也有dispose
回调,其中你想在 build
函数之外定义)并且你使用 CupertinoTabScaffold
文档指出:
You must listen to the onTap callbacks and call setState with a new currentIndex for the new selection to reflect. This can also be done automatically by wrapping this with a CupertinoTabScaffold.
取自 here。因此,如果您不使用 CupertinoTabScaffold
,我的原始答案将适用。在您的情况下,您的 class 应该如下所示:
class _HomePageState extends State<HomePage> {
// Placing the _controller as a property of your class
// instead of a local variable inside your build method
// which would be re-instantiated on every build call -
// as in the case of hot reload
CupertinoTabController _controller = CupertinoTabController();
// Also setting the dispose function correctly outside
// of the build function
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
List<Widget> tabs = [
HomeScreen(_controller),
PlaySearchScreen(),
HomeScreen(_controller),
ProfileScreen(),
];
...
原版
CupertinoTabBar
有一个 currentIndex
属性 来维护选定的选项卡。因此,您需要在 _HomePageState
:
class _HomePageState extends State<HomePage> {
// Variable to maintain current tab index.
// Setting it to 0 (first tab) as default here
int _index = 0;
...
}
然后在实际的 CupertinoTabBar
中,我们添加设置 currentIndex
属性 并使用 onTap
回调相应地更新我们的 属性:
CupertinoTabBar(
// Setting the index
currentIndex: _index,
// Callback to update our index once a tab is clicked
onTap: (index) => setState(() => _index = index),
items: [
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.play),
label: 'Play Tennis',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.calendar),
label: ' My Schedule',
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.person),
label: 'Profile',
),
],
),