UI 仅在 Flutter 热重载或重启后响应
UI is responding only after Hot reload or restart in Flutter
我喜欢在向下滚动时隐藏 floatingActionButton
并在向上滚动时显示它。但只有在热重启或重载后才有效
transaction.dart
class Transaction extends StatefulWidget {
const Transaction({Key? key}) : super(key: key);
@override
State<Transaction> createState() => _TransactionState();
}
bool isFab = false;
class _TransactionState extends State<Transaction> {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
body: SafeArea(
child: NestedScrollView(
floatHeaderSlivers: true,
headerSliverBuilder: (context, innerBoxIsScrolled) => [
SliverAppBar(
pinned: true,
floating: true,
snap: true,
centerTitle: true,
title: Text(
"Money Manager",
style: TextStyle(letterSpacing: 1.5),
strutStyle: StrutStyle(
fontSize: 20, fontStyle: FontStyle.normal),
),
bottom: TabBar(tabs: [
Tab(
child: Text(
"Income",
style:
TextStyle(fontSize: 18, letterSpacing: 1.5),
),
),
Tab(
child: Text(
"Expense",
style:
TextStyle(fontSize: 18, letterSpacing: 1.5),
),
)
]),
)
],
body: TabBarView(children: [Income(), Expense()]))),
floatingActionButton: isFab ? Fab() : null,
),
);
}
}
expense.dart
class Expense extends StatefulWidget {
const Expense({Key? key}) : super(key: key);
@override
State<Expense> createState() => _ExpenseState();
}
class _ExpenseState extends State<Expense> {
@override
Widget build(BuildContext context) {
return NotificationListener<UserScrollNotification>(
onNotification: (notification) {
if (notification.direction == ScrollDirection.forward) {
setState(() => isFab = true);
} else if (notification.direction == ScrollDirection.reverse) {
setState(() => isFab = false);
}
return true;
},
child: ListView.separated(
itemBuilder: (context, index) {
return ListTile(
leading: CircleAvatar(),
trailing: Text("- ₹2000"),
title: Text("category"),
subtitle: Text(formatter),
);
},
separatorBuilder: (context, index) {
return Divider();
},
itemCount: 30),
);
}
}
在您的代码中,isFab
被声明为 false
全局变量,因此它不会被 setState
调用更改。我不完全知道为什么它在热重载或重启后开始工作。
要让它工作,你必须让它成为 _TransactionState
的一部分,而且你还必须让它可以从 ExpenseState
访问,因为你把 NotificationListener
放在那里。
但可能最简单的解决方案是将 Transaction
中的 NotificationListener
作为 Scaffold
的主体移动,然后将 isFab
变量声明为 _TransactionState
。
你可以看到它here:我不得不改变一些东西(比如使用默认的FAB)来制作飞镖运行,但现在FAB只在最上面出现。
我喜欢在向下滚动时隐藏 floatingActionButton
并在向上滚动时显示它。但只有在热重启或重载后才有效
transaction.dart
class Transaction extends StatefulWidget {
const Transaction({Key? key}) : super(key: key);
@override
State<Transaction> createState() => _TransactionState();
}
bool isFab = false;
class _TransactionState extends State<Transaction> {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
body: SafeArea(
child: NestedScrollView(
floatHeaderSlivers: true,
headerSliverBuilder: (context, innerBoxIsScrolled) => [
SliverAppBar(
pinned: true,
floating: true,
snap: true,
centerTitle: true,
title: Text(
"Money Manager",
style: TextStyle(letterSpacing: 1.5),
strutStyle: StrutStyle(
fontSize: 20, fontStyle: FontStyle.normal),
),
bottom: TabBar(tabs: [
Tab(
child: Text(
"Income",
style:
TextStyle(fontSize: 18, letterSpacing: 1.5),
),
),
Tab(
child: Text(
"Expense",
style:
TextStyle(fontSize: 18, letterSpacing: 1.5),
),
)
]),
)
],
body: TabBarView(children: [Income(), Expense()]))),
floatingActionButton: isFab ? Fab() : null,
),
);
}
}
expense.dart
class Expense extends StatefulWidget {
const Expense({Key? key}) : super(key: key);
@override
State<Expense> createState() => _ExpenseState();
}
class _ExpenseState extends State<Expense> {
@override
Widget build(BuildContext context) {
return NotificationListener<UserScrollNotification>(
onNotification: (notification) {
if (notification.direction == ScrollDirection.forward) {
setState(() => isFab = true);
} else if (notification.direction == ScrollDirection.reverse) {
setState(() => isFab = false);
}
return true;
},
child: ListView.separated(
itemBuilder: (context, index) {
return ListTile(
leading: CircleAvatar(),
trailing: Text("- ₹2000"),
title: Text("category"),
subtitle: Text(formatter),
);
},
separatorBuilder: (context, index) {
return Divider();
},
itemCount: 30),
);
}
}
在您的代码中,isFab
被声明为 false
全局变量,因此它不会被 setState
调用更改。我不完全知道为什么它在热重载或重启后开始工作。
要让它工作,你必须让它成为 _TransactionState
的一部分,而且你还必须让它可以从 ExpenseState
访问,因为你把 NotificationListener
放在那里。
但可能最简单的解决方案是将 Transaction
中的 NotificationListener
作为 Scaffold
的主体移动,然后将 isFab
变量声明为 _TransactionState
。
你可以看到它here:我不得不改变一些东西(比如使用默认的FAB)来制作飞镖运行,但现在FAB只在最上面出现。