这是一个有趣的问题,我有一些时间来处理这个问题,并且我在日志中看到滚动控制器似乎更新得很好。但是,由于某种原因,它不起作用,所以我在列表周围放置了滚动视图,并且没有给 ListView.builder 滚动。只有这个要考虑的是列表的最后部分,因为如果你在最后部分,你不想向下滚动更多,因为你不能再向下滚动。
这可能不是最好的解决方案,但它是我设法放在一起的,希望这会有所帮助。
import 'dart:developer';
import 'package:flutter/material.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 Scroll Bug Demo',
home: MainScreen(),
);
}
}
class MainScreen extends StatefulWidget {
@override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
final _demoList = List.generate(100, (index) => 'List Item $index');
int _expandedIndex = -1;
final _scrollController = ScrollController();
bool _isExpanded = false;
bool _isInLastPart = false;
@override
Widget build(BuildContext context) {
_isInLastPart = (_expandedIndex > _demoList.length - 15);
final _size = MediaQuery.of(context).size;
return SafeArea(
child: Scaffold(
body: SingleChildScrollView(
controller: _scrollController,
child: SizedBox(
height: (48 * _demoList.length).toDouble() +
((_isExpanded && _isInLastPart) ? 80 : 0).toDouble(),
width: _size.width,
child: ListView.builder(
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return GestureDetector(
onTap: () => clickItem(index),
child: Container(
color: Colors.grey,
height: (_expandedIndex == index && _isExpanded) ? 120 : 40,
margin: EdgeInsets.only(bottom: 8),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(_demoList[index]),
if (_expandedIndex == index && _isExpanded)
Column(
children: <Widget>[
Text('text'),
Text('text'),
Text('text'),
Text('text'),
Text('text'),
],
),
],
),
),
);
},
itemCount: _demoList.length,
),
),
),
),
);
}
clickItem(int index) {
setState(() {
if (_expandedIndex == index)
_isExpanded = !_isExpanded;
else
_isExpanded = true;
_expandedIndex = index;
});
if (_expandedIndex < _demoList.length - 15) {
// log("expanded index_: $_expandedIndex, index: $index, jump to: ${index * 48.toDouble()}/${99 * 48.toDouble()}, scroll> ${_scrollController.position.pixels},isExpanded: $_isExpanded");
_scrollController.jumpTo(index * 48.toDouble());
} else {
if (_isExpanded) {
// log("expanded index_: $_expandedIndex, index: $index, jump to: ${83 * 48.toDouble() + 8}/${99 * 48.toDouble()}, scroll> ${_scrollController.offset},isExpanded: $_isExpanded");
_scrollController.jumpTo(83 * 48.toDouble() + 80 + 8);
} else {
// log("expanded index_: $_expandedIndex, index: $index, jump to: ${83 * 48.toDouble() + 80 + 8}/${99 * 48.toDouble()}, scroll> ${_scrollController.offset}, isExpanded: $_isExpanded");
_scrollController.jumpTo(83 * 48.toDouble() + 8);
}
}
}
}