如何在 StreamBuilder 中更新 Flutter Cards 而无需重置状态?
Posted
技术标签:
【中文标题】如何在 StreamBuilder 中更新 Flutter Cards 而无需重置状态?【英文标题】:How to update Flutter Cards in StreamBuilder without reseting state? 【发布时间】:2018-03-19 21:34:59 【问题描述】:我让 StreamBuilder 正常工作。 1 件事,每次 1 个元素更改时,整个列表都会重置。例如,每张卡片都有一个计数器,我希望在不改变屏幕的情况下看到加减法。我怎样才能做到这一点?这是我的代码(使用完整的文件堆栈更新)...
final FirebaseAuth _auth = FirebaseAuth.instance;
final fb = FirebaseDatabase.instance.reference();
final falQuery = fb.child('NumberOnes').orderByChild('Value');
final streamQuery = fb.child('NumberOnes').orderByChild('Value').onValue;
class NumberOnesPage extends StatefulWidget
@override
NumberOnesPageState createState() => new NumberOnesPageState();
class NumberOnesPageState extends State<NumberOnesPage>
List names = new List();
List numbers = new List();
List ids = new List();
List vidImages = new List();
void _handleJson(value)
Map myMap = value; //store each map
var titles = myMap.values;
for (var items in titles)
names.add(items['vidTitle']);
numbers.add(items['Value']);
ids.add(items['vidId']);
vidImages.add(items['vidImage']);
@override
Widget build(BuildContext context)
return new Scaffold(
appBar: new AppBar(
backgroundColor: Colors.amber,
title: new Text(
'Number Ones',
style:
new TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
),
),
body: new Container(
child: new Center(
child: new Column(
children: <Widget>[
new Flexible(
child: new FirebaseAnimatedList(
query: falQuery,
padding: new EdgeInsets.all(15.0),
//sort: (a, b) => b.key.compareTo(a.key),
reverse: false,
itemBuilder: (_, DataSnapshot followerSnap,
Animation<double> animation, int Index)
return new StreamBuilder<Event>(
stream: streamQuery,
builder: (BuildContext context,
AsyncSnapshot<Event> event)
switch (event.connectionState)
case ConnectionState.none:
return new Card(
child: new Text('Loading...',
style: new TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.bold,
fontStyle: FontStyle.italic)),
);
case ConnectionState.waiting:
return new Card(
child: new Text('Awaiting Results...',
style: new TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.bold,
fontStyle: FontStyle.italic)),
);
default:
if (event.hasError)
return new Card(
child: new Text('Error: $event.error',
style: new TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.bold,
fontStyle: FontStyle.italic)),
);
else
_handleJson(event.data.snapshot.value);
return new InkWell(
splashColor: Colors.blueAccent,
onTap: ()
Navigator.push(
context,
new MaterialPageRoute(
builder: (_) =>
new Video.VideoPage()));
Video.id = ids[Index];
Video.title = names[Index];
Video.videoImage = vidImages[Index];
,
child: new Card(
child: new Column(
children: <Widget>[
new Padding(
padding: new EdgeInsets.all(5.0)),
new Image.network(vidImages[Index]),
new Padding(
padding: new EdgeInsets.all(3.0)),
new Text(
'$numbers[Index] MyFavKPopers Have Made This Their #1'),
new Padding(
padding: new EdgeInsets.all(3.0)),
new Text(
names[Index],
style: new TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
color: Colors.black),
//textAlign: TextAlign.center,
),
new Padding(
padding: new EdgeInsets.all(5.0)),
],
),
),
);
);
))
],
)),
));
例如,我希望 numbers[Index]
改变甚至卡片根据数值上下移动而不完全改变 UI。
【问题讨论】:
您能添加一个工作代码示例吗?我真的不知道如何让你的代码运行。最好没有外部依赖。 @RainerWittmann 我已经添加了完整的堆栈。 【参考方案1】:有一个小部件可以做到这一点:IndexedStack,它保留堆栈中所有子级的状态,同时允许您在它们之间切换:
IndexedStack(
index: _widgetIndex,
children: [
WidgetOne(),
WidgetTwo()
]
)
您可以在代码中的任何位置使用 setState() 通过修改 _widgetIndex 的值来更改应显示的小部件
setState(() => _widgetIndex = 2);
【讨论】:
以上是关于如何在 StreamBuilder 中更新 Flutter Cards 而无需重置状态?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 StreamBuilder 更新 TextField 的值?
如何更新 Storage 中的图片并刷新 Streambuilder 以显示新图片?
Flutter:从子 StreamBuilder 更新有状态小部件
Flutter StreamBuilder中使用的Firestore快照在数据更改时永远不会更新