gpt4 book ai didi

Flutter问题: listview rebuilding items when scrolled

转载 作者:行者123 更新时间:2023-12-03 13:29:28 25 4
gpt4 key购买 nike

当我滚动到 ListView 的底部时,底部的项将被重建。当我滚动到顶部时,我的第一个项目被重建。第一项是带有可选筹码的卡,这种筹码在发生这种情况时会被取消选择。并且“入口”动画也会重播。我该如何阻止呢?

这是基本的代码(它使用了simple_animations包,我似乎无法重现芯片的问题,但动画仍然有问题):

import 'package:flutter/material.dart';
import 'package:simple_animations/simple_animations.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}

class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
final List _chips = ['Hello', 'World'];

List _selected = [];

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Issue demo'),
),
body: ListView(
children: <Widget>[
FadeIn(
1,
Card(
child: Wrap(
spacing: 10,
children: List<Widget>.generate(
_chips.length,
(int index) => InputChip(
label: Text(_chips[index]),
selected: _selected.contains(_chips[index]),
onSelected: (selected) {
setState(() {
if (selected) {
_selected.add(_chips[index]);
} else {
_selected.remove(_chips[index]);
}
});
}),
),
),
),
),
FadeIn(1.5, Text('A', style: Theme.of(context).textTheme.display4)),
FadeIn(2, Text('Very', style: Theme.of(context).textTheme.display4)),
FadeIn(2.5, Text('Big', style: Theme.of(context).textTheme.display4)),
FadeIn(3, Text('Scroll', style: Theme.of(context).textTheme.display4)),
FadeIn(3.5, Text('View', style: Theme.of(context).textTheme.display4)),
FadeIn(4, Text('With', style: Theme.of(context).textTheme.display4)),
FadeIn(4.5, Text('Lots', style: Theme.of(context).textTheme.display4)),
FadeIn(5, Text('Of', style: Theme.of(context).textTheme.display4)),
FadeIn(5.5,Text('Items', style: Theme.of(context).textTheme.display4)),
FadeIn(
6,
Card(
child: Text('Last item',
style: Theme.of(context).textTheme.display2),
),
),
],
),
);
}
}

class FadeIn extends StatelessWidget {
final double delay;
final Widget child;

FadeIn(this.delay, this.child);

@override
Widget build(BuildContext context) {
final tween = MultiTrackTween([
Track("opacity")
.add(Duration(milliseconds: 500), Tween(begin: 0.0, end: 1.0)),
Track("translateX").add(
Duration(milliseconds: 500), Tween(begin: 130.0, end: 0.0),
curve: Curves.easeOut)
]);

return ControlledAnimation(
delay: Duration(milliseconds: (300 * delay).round()),
duration: tween.duration,
tween: tween,
child: child,
builderWithChild: (context, child, animation) => Opacity(
opacity: animation["opacity"],
child: Transform.translate(
offset: Offset(animation["translateX"], 0), child: child),
),
);
}
}


您应该自己运行此程序以完全理解问题

最佳答案

要使ListView中的元素保持事件状态(向后滚动时不重新渲染),应使用用户参数addAutomaticKeepAlives: true。并且ListView中的每个元素都必须是带有AutomaticKeepAliveClientMixin的StatefulWidget。

这是我为您编辑的代码

import 'package:flutter/material.dart';
import 'package:simple_animations/simple_animations.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}

class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
final List _chips = ['Hello', 'World'];

List _selected = [];

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Issue demo'),
),
body: ListView(
addAutomaticKeepAlives: true,
children: <Widget>[
FadeIn(
1,
Card(
child: Wrap(
spacing: 10,
children: List<Widget>.generate(
_chips.length,
(int index) => InputChip(
label: Text(_chips[index]),
selected: _selected.contains(_chips[index]),
onSelected: (selected) {
setState(() {
if (selected) {
_selected.add(_chips[index]);
} else {
_selected.remove(_chips[index]);
}
});
}),
),
),
),
),
FadeIn(1.5, Text('A', style: Theme.of(context).textTheme.display4)),
FadeIn(2, Text('Very', style: Theme.of(context).textTheme.display4)),
FadeIn(2.5, Text('Big', style: Theme.of(context).textTheme.display4)),
FadeIn(3, Text('Scroll', style: Theme.of(context).textTheme.display4)),
FadeIn(3.5, Text('View', style: Theme.of(context).textTheme.display4)),
FadeIn(4, Text('With', style: Theme.of(context).textTheme.display4)),
FadeIn(4.5, Text('Lots', style: Theme.of(context).textTheme.display4)),
FadeIn(5, Text('Of', style: Theme.of(context).textTheme.display4)),
FadeIn(5.5,Text('Items', style: Theme.of(context).textTheme.display4)),
FadeIn(
6,
Card(
child: Text('Last item',
style: Theme.of(context).textTheme.display2),
),
),
],
),
);
}
}

class FadeIn extends StatefulWidget {
final double delay;
final Widget child;
FadeIn(this.delay, this.child);
_FadeInState createState() => _FadeInState();
}

class _FadeInState extends State<FadeIn> with AutomaticKeepAliveClientMixin {

@override
Widget build(BuildContext context) {
final tween = MultiTrackTween([
Track("opacity")
.add(Duration(milliseconds: 500), Tween(begin: 0.0, end: 1.0)),
Track("translateX").add(
Duration(milliseconds: 500), Tween(begin: 130.0, end: 0.0),
curve: Curves.easeOut)
]);

return ControlledAnimation(
delay: Duration(milliseconds: (300 * widget.delay).round()),
duration: tween.duration,
tween: tween,
child: widget.child,
builderWithChild: (context, child, animation) => Opacity(
opacity: animation["opacity"],
child: Transform.translate(
offset: Offset(animation["translateX"], 0), child: child),
),
);
}

@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
}

关于Flutter问题: listview rebuilding items when scrolled,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57980225/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com