我正在使用 CustomScrollView
并尝试在 SliverAppBar
操作中添加一个喜欢按钮,通过点击它,它的形状会发生变化。我正在 setState
内进行更改。但是尽管调用了 build 方法,但 UI 并未更新。
TextButton(
onPressed: () {
bool added = courseStore.addToUserFavoriteCourses(widget.courseDetails);
added ?
setState(() {
iconData = Icons.favorite;
}) :
setState(() {
iconData = Icons.favorite_border;
});
},
child: Icon(
iconData,
size: 20,
color: Colors.white,
),
)
答案 0 :(得分:1)
上面的代码还没有保存 iconData
的状态。
喜欢/不喜欢的状态需要向上移动到父小部件范围内。然后可以在子级中下面引用它的值,例如 TextButton。
当 TextButton 被重建(从不喜欢变为喜欢和返回)时,它可以使用它上面持续存在的状态。
请注意以下 iconData
是如何存在于 State 小部件中的。此小部件旨在为其子项保持状态。
您可以将此代码复制粘贴到 Flutter/Dart 文件中进行测试:
import 'package:flutter/material.dart';
// ↓ Use this as your button
class StatefulButton extends StatefulWidget {
final double size;
final Color color;
StatefulButton({this.size = 20, this.color = Colors.black});
@override
_StatefulButtonState createState() => _StatefulButtonState();
}
class _StatefulButtonState extends State<StatefulButton> {
IconData iconData = Icons.favorite_border;
// ↑ Move your state up to here
@override
Widget build(BuildContext context) {
return Center(
child: TextButton(
child: Icon(
iconData,
size: widget.size,
color: widget.color,
),
onPressed: toggleLike,
),
);
}
void toggleLike() {
setState(() {
iconData = iconData == Icons.favorite ? Icons.favorite_border : Icons.favorite;
});
}
}
/// Just a container page for the example above
class TextButtonStatePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('TextButtonState'),
),
body: StatefulButton()
);
}
}
以下是在 CustomScrollView 中使用上述 StatefulButton 的示例。我窃取的 CustomScrollView 代码 straight from the Flutter docs website。我所做的唯一编辑是将上面的 StatefulButton 添加到每个条带中,以显示它在单击时更改其状态。
/// Flutter code sample for CustomScrollView
import 'package:flutter/material.dart';
import 'text_button_state.dart';
/// This is the stateful widget that the main application instantiates.
class CustomScrollviewPage extends StatefulWidget {
CustomScrollviewPage({Key key}) : super(key: key);
@override
_CustomScrollviewPageState createState() => _CustomScrollviewPageState();
}
/// This is the private State class that goes with MyStatefulWidget.
class _CustomScrollviewPageState extends State<CustomScrollviewPage> {
List<int> top = [];
List<int> bottom = [0];
@override
Widget build(BuildContext context) {
const Key centerKey = ValueKey('bottom-sliver-list');
return Scaffold(
appBar: AppBar(
title: const Text('Press on the plus to add items above and below'),
leading: IconButton(
icon: const Icon(Icons.add),
onPressed: () {
setState(() {
top.add(-top.length - 1);
bottom.add(bottom.length);
});
},
),
),
body: CustomScrollView(
center: centerKey,
slivers: <Widget>[
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
alignment: Alignment.center,
color: Colors.blue[200 + top[index] % 4 * 100],
height: 100 + top[index] % 4 * 20.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Item: ${top[index]}'),
StatefulButton() // ← STATEFUL BUTTON HERE
],),
);
},
childCount: top.length,
),
),
SliverList(
key: centerKey,
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
alignment: Alignment.center,
color: Colors.blue[200 + bottom[index] % 4 * 100],
height: 100 + bottom[index] % 4 * 20.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Item: ${bottom[index]}'),
StatefulButton() // ← STATEFUL BUTTON HERE
],
),
);
},
childCount: bottom.length,
),
),
],
),
);
}
}