Listview 使用新项目保持列表中的位置颤振列表视图
我正在构建一个颤振应用程序,但ListView.builder出现了问题 我当前的设置是一个StreamBuilder,它有一个对象列表。每个对象都绑定到ListView.builder中的一个项目 我的问题是,当添加新项目时,我调用StreamController$add()时,列表会自动滚动到列表的顶部。我正在寻找要维护的列表位置,由用户(或按钮)滚动到顶部 我已经在列表项中添加了键,这有助于解决其他问题,但这次没有。我还向listview添加了一个PageStorageKey,但这没有帮助。我也有一个滚动控制器,但还没有弄清楚如何工作这种行为 如果需要,我可以提供代码示例。提前谢谢 相关代码:Listview 使用新项目保持列表中的位置颤振列表视图,listview,flutter,Listview,Flutter,我正在构建一个颤振应用程序,但ListView.builder出现了问题 我当前的设置是一个StreamBuilder,它有一个对象列表。每个对象都绑定到ListView.builder中的一个项目 我的问题是,当添加新项目时,我调用StreamController$add()时,列表会自动滚动到列表的顶部。我正在寻找要维护的列表位置,由用户(或按钮)滚动到顶部 我已经在列表项中添加了键,这有助于解决其他问题,但这次没有。我还向listview添加了一个PageStorageKey,但这没有帮助
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: albatrossDarkTheme,
home: TimelinePage(),
);
}
}
class TimelinePage extends StatefulWidget {
TimelinePage({Key key}) : super(key: key);
@override
_TimelinePageState createState() => _TimelinePageState();
}
class _TimelinePageState extends State<TimelinePage> {
AlbatrossClient _client;
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
PageStorageKey _pageKey = PageStorageKey(8);
TimelineDatabase _database = TimelineDatabase();
StreamController<List<Tweet>> _controller;
ScrollController _scrollController;
Stream<List<Tweet>> _getStream() {
return _controller.stream;
}
Future<void> _refreshTimeline() async {
_client.refreshTimeline().then((result) {
if (result == 0)
_database.getTimeline(false).then((update) {
_controller.add(update);
});
});
}
_updateTimeline() async {
_database.getTimeline(false).then((update) => _controller.add(update));
}
@override
void initState() {
_client = AlbatrossClient();
_controller = StreamController<List<Tweet>>();
_scrollController = ScrollController(keepScrollOffset: true);
_database.getTimeline(false).then((saved) => _controller.add(saved));
_client.refreshTimeline().then((result) {
if (result == 0)
_database.getTimeline(false).then((update) {
_controller.add(update);
});
});
super.initState();
}
@override
void dispose() {
_controller.close();
_scrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: SearchAppbar(() {
_scaffoldKey.currentState.openDrawer();
}),
drawer: Drawer(
child: DrawerMain.getDrawer(context, _client.getProfile()),
),
body: Container(
child: RefreshIndicator(
onRefresh: _refreshTimeline,
child: StreamBuilder<List<Tweet>>(
stream: _getStream(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
key: _pageKey,
controller: _scrollController,
itemCount:
snapshot.data != null ? snapshot.data.length : 0,
itemBuilder: (context, index) {
return RowTweet(
tweet: snapshot.data[index],
update: _updateTimeline,
animate: true);
},
);
} else
return Container(
alignment: Alignment(0.0, 0.0),
child: CircularProgressIndicator(),
);
},
))),
floatingActionButton: FloatingActionButton(
tooltip: 'Compose Tweet',
onPressed: _composeTweet,
foregroundColor: Colors.white,
child: Image.asset(
"icons/ic_tweet_web.webp",
width: 38,
height: 38,
),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
因此,每次通过流发出新值时,都会重新生成整个列表视图。解决此问题的方法是将列表视图移出流生成器,并仅在流生成器中修改列表视图的子级 我以前没有广泛使用过StreamBuilder,所以您必须在代码中找到它。有两种方法可以解决这个问题
似乎我需要添加代码,因为事实上我正在使用一个有状态的widgetYep,拥有代码将帮助我们解决问题。@NickMowen更改了答案。我添加了第二次尝试,但仍然不起作用,并在添加新项目时移到顶部。有趣的是,无论是流生成器还是这个新尝试,比如推特(更新数据库和流/列表)都不会移动列表,但添加新项目似乎会将其推到顶部。它似乎不一定会滚动到顶部,只是列表会随着添加的新项目的高度而跳跃。我正在尝试禁用此跳转
return Scaffold(
key: _scaffoldKey,
appBar: SearchAppbar(() {
_scaffoldKey.currentState.openDrawer();
}),
drawer: Drawer(
child: DrawerMain.getDrawer(context, _client.getProfile()),
),
body: Container(
child: RefreshIndicator(
onRefresh: _refreshTimeline,
child: _timeline.isNotEmpty
? ListView.builder(
key: _pageKey,
controller: _scrollController,
itemCount: _timeline.length,
itemBuilder: (context, index) {
return RowTweet(
tweet: _timeline[index],
update: _updateTimeline,
animate: true);
})
: Container(
alignment: Alignment(0, 0),
child: CircularProgressIndicator(),
))),
floatingActionButton: FloatingActionButton(
tooltip: 'Compose Tweet',
onPressed: _composeTweet,
foregroundColor: Colors.white,
child: Image.asset(
"icons/ic_tweet_web.webp",
width: 38,
height: 38,
),
), // This trailing comma makes auto-formatting nicer for build methods.
);