update @man of knowledge's code,
( ListView in ListView ),
to Dart 2.15.1
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(title: 'Flutter Demo', home: MyListView());
}
}
class MyListView extends StatelessWidget {
ScrollController _mainScrollController = ScrollController();
double listHeight = 370;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('AppBar'),
),
body: Container(
height: MediaQuery.of(context).size.height,
child: ListView(
controller: _mainScrollController,
children: <Widget>[
Container(
height: listHeight, child: RapportList(_mainScrollController)),
OtherElement(
"Other element 1 which will be scrolled",
),
OtherElement(
"Other element 2 which will be scrolled",
),
OtherElement(
"Other element 3 which will be scrolled",
),
OtherElement(
"Other element 4 which will be scrolled",
),
OtherElement(
"Other element 5 which will be scrolled",
),
],
),
),
);
}
}
class RapportList extends StatefulWidget {
final ScrollController parentScrollController;
RapportList(this.parentScrollController);
@override
_RapportListState createState() => _RapportListState();
}
class _RapportListState extends State<RapportList> {
late ScrollController _listViewScrollController = ScrollController()
..addListener(listViewScrollListener);
ScrollPhysics _physics = ScrollPhysics();
// NeverScrollableScrollPhysics()
void listViewScrollListener() {
print("smth");
if (_listViewScrollController.offset >=
_listViewScrollController.position.maxScrollExtent &&
!_listViewScrollController.position.outOfRange) {
if (widget.parentScrollController.offset == 0) {
widget.parentScrollController.animateTo(50,
duration: Duration(milliseconds: 200), curve: Curves.linear);
}
setState(() {
_physics = NeverScrollableScrollPhysics();
});
print("bottom");
}
}
void mainScrollListener() {
if (widget.parentScrollController.offset <=
widget.parentScrollController.position.minScrollExtent &&
!widget.parentScrollController.position.outOfRange) {
setState(() {
if (_physics is NeverScrollableScrollPhysics) {
_physics = ScrollPhysics();
_listViewScrollController.animateTo(
_listViewScrollController.position.maxScrollExtent - 50,
duration: Duration(milliseconds: 200),
curve: Curves.linear);
}
});
print("top");
}
}
@override
Widget build(BuildContext context) {
widget.parentScrollController.addListener(mainScrollListener);
return ListView.builder(
controller: _listViewScrollController,
physics: _physics,
shrinkWrap: true,
itemCount: 50,
itemBuilder: (context, index) {
return ListTile(
title: GestureDetector(
child: Row(
children: <Widget>[
Container(child: Text("text $index")),
],
),
),
);
},
);
}
}
class OtherElement extends StatelessWidget {
final String text;
OtherElement(this.text);
@override
Widget build(BuildContext context) {
return Container(
height: 100,
child: Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 40.0),
child: Text(this.text, style: TextStyle(fontSize: 30)),
)),
);
}
}