如何结合singlechildscrollview和listview的滚动?我试图创建一个布局,其中有一个singlechildscrollview,其中包含包装一些小部件和listview的列。如何结合滚动视图和列表视图的滚动控制器。 (即,我希望列表视图仅在其他窗口小部件滚动和不显示时滚动,并且仅在到达列表视图顶部时再次显示。)例如:在instagram应用中,您具有类似用户图像,用户名,关注者计数,关注计数等,然后有一个列表视图列出了用户的帖子。滚动条已连接。我该如何实现??
答案 0 :(得分:1)
当嵌套的listview到达顶部时,我可以编写滚动父级的解决方案。这是我代码的一部分-我有2个元素的ListView。第二个是另一个ListView
class _ConferenceScaffoldState extends CommonScaffoldState<ConferenceScaffold> {
final ScrollController controller = ScrollController();
final GlobalKey widgetKey = GlobalKey();
/* widgetKey is for widget in buildHeaderRow() */
StreamController<bool> _streamController = StreamController<bool>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(conference_title),
centerTitle: true,
),
body: getBody(),
);
}
Widget getBody() {
controller.addListener((){
if (widgetKey.currentContext != null) {
double height = widgetKey.currentContext.size.height;
_streamController.add(controller.offset >= height);
}
});
return ListView(
controller: controller,
children: <Widget>[buildHeaderRow(), buildPagerRow()],
);
}
Widget buildPagerRow() => _EventSpeakerPager(scrollCallback, _streamController.stream);
scrollCallback(double position) => controller.position.jumpTo(controller.position.pixels - position);
@override
void dispose() {
controller.dispose();
super.dispose();
}
}
typedef ScrollCallback = void Function(double position);
class _EventSpeakerPager extends StatefulWidget {
_EventSpeakerPager(this.callback, this.stream);
final ScrollCallback callback;
final Stream<bool> stream;
@override
State<StatefulWidget> createState() => _EventSpeakerPagerState();
}
class _EventSpeakerPagerState extends State<_EventSpeakerPager> {
final GlobalKey tabKey = GlobalKey();
bool isChildScrollEnabled = false;
@override
void initState() {
super.initState();
widget.stream.distinct().listen((bool data) {
setState(() {
isChildScrollEnabled = data;
});
});
}
@override
Widget build(BuildContext context) {
ListView eventList = ListView.builder(
physics: isChildScrollEnabled ? AlwaysScrollableScrollPhysics() : NeverScrollableScrollPhysics(),
controller: ScrollController(),
itemBuilder: (buildContext, position) {
if (position.isOdd) return CommonDivider();
return buildEventRow(getEventList()[position ~/ 2], false, null);
},
itemCount: getEventList().length * 2,
);
return Listener(
onPointerMove: (event) {
double pixels = eventList.controller.position.pixels;
if (event.delta.dy > 0.0 && pixels == 0.0) widget.callback(event.delta.dy);
},
child: ...,
);
}
}
UPD 添加了用于更改带流子的滚动物理的解决方案
答案 1 :(得分:0)
我建立自己的Listview,就像这样:
List<String> myList = ["one", "two", "three", "four"]; //Just some example list data
ListView.builder(,
itemCount: myList.length,
itemBuilder: (BuildContext context, int index) {
return TileWidget(
myList[index],
index == 0, //this indicates that it is the first item
index == myList.length - 1); //this indicates that it is the last item
},
),
然后像这样构建我的“ TileWidget”:
class TileWidget extends StatelessWidget {
TileWidget(this.tileData, this.isFirstItem, this.isLastItem,);
String tileData;
bool isFirstItem;
bool isLastItem;
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
isFirstItem ? Text("this is a title") : Container(),
Text(tileData),
isLastItem ? Text("This is a footer") : Container(),
],
);
}
}
不是很漂亮。但这很简单并且有效。
答案 2 :(得分:0)
这可能有点晚了,但是您可以像这样将 NeverScrollableScrollPhysics() 添加到 ListView 的物理参数:
document.getElementsByClassName('chat incoming').length