#flutter #listview #flutter-pageview #scrollcontroller
Вопрос:
Я хочу DraggableScrollableSheet
, чтобы он начал сворачиваться, когда внутренний список (тот, что внутри ItCrowdPage
) достигнет вершины, я попытался обернуть его, NotificationListener
но это не работает.
Метод, который я испробовал :-
NotificationListenerlt;OverscrollNotificationgt;( onNotification: (value) { if (value.overscroll lt; 0 amp;amp; widget.scrollController.offset value.overscroll lt;= 0) { if (widget.scrollController.offset != 0) widget.scrollController.jumpTo(0); } else if (widget.scrollController.offset value.overscroll gt;= widget.scrollController.position .maxScrollExtent) { if (widget.scrollController.offset != widget.scrollController.position .maxScrollExtent) widget.scrollController.jumpTo(widget .scrollController .position .maxScrollExtent); } widget.scrollController.jumpTo( widget.scrollController.position.pixels value.overscroll); return true; }, child: ListView( children: [ Padding( padding: const EdgeInsets.only(bottom: 10.0), child: Text( listOfCharacters[index]['name'], textAlign: TextAlign.center, style: TextStyle(fontSize: 20), ), ), Container( color: cc[index], height: 50, ), Container( color: Colors.red, height: 500, ) ], ), );
Полный снип кода :
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; void main() =gt; runApp( const MyApp(), ); /// This is the main application widget. class MyApp extends StatelessWidget { const MyApp({Key key}) : super(key: key); static const String _title = 'Flutter Code Sample'; @override Widget build(BuildContext context) { return MaterialApp( title: _title, home: Scaffold( appBar: AppBar(title: const Text(_title)), body: const MyStatelessWidget(), ), ); } } class MyStatelessWidget extends StatelessWidget { const MyStatelessWidget({Key key}) : super(key: key); @override Widget build(BuildContext context) { return Center( child: Stack(children: [ DraggableScrollableSheet( initialChildSize: 0.6, minChildSize: 41 / MediaQuery.of(context).size.height, maxChildSize: 0.6, builder: (BuildContext context, ScrollController scrollController) { return ItCrowdPage( scrollController: scrollController, ); }, ), ])); } } class ClampScroll extends ScrollBehavior { @override Widget buildViewportChrome( BuildContext context, Widget child, AxisDirection axisDirection) { return child; } } class ItCrowdPage extends StatefulWidget { final ScrollController scrollController; const ItCrowdPage({Key key, @required this.scrollController}) : super(key: key); @override _ItCrowdPageState createState() =gt; _ItCrowdPageState(); } class _ItCrowdPageState extends Statelt;ItCrowdPagegt; { double viewPortFraction = 0.5; PageController pageController, pageController2; int currentPage = 0; Listlt;Maplt;String, Stringgt;gt; listOfCharacters = [ {'name': "Richmond"}, {'name': "Roy"}, {'name': "Moss"}, {'name': "Douglas"}, {'name': "Jen"} ]; double page = 0.0; bool sc = false, sc2 = false; @override void initState() { pageController = PageController( initialPage: currentPage, viewportFraction: viewPortFraction); pageController2 = PageController(initialPage: currentPage); super.initState(); } @override void dispose() { pageController.dispose(); pageController2.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Container( clipBehavior: Clip.antiAlias, decoration: const BoxDecoration( color: Colors.pink, borderRadius: const BorderRadius.only( topLeft: Radius.circular(20), topRight: Radius.circular(20))), child: ScrollConfiguration( behavior: ClampScroll(), child: CustomScrollView( controller: widget.scrollController, slivers: [ SliverFillRemaining( child: Column( children: [ Container( margin: EdgeInsets.all(10), width: 42, height: 6, decoration: BoxDecoration( color: Colors.grey.shade300, borderRadius: const BorderRadius.all(Radius.circular(8))), ), // Expanded( // child: Container( // color: Colors.blueAccent, // )) const SizedBox( height: 9, ), Flexible( flex: 1, fit: FlexFit.loose, child: NotificationListenerlt;ScrollNotificationgt;( onNotification: (ScrollNotification notification) { if (notification is UserScrollNotification amp;amp; sc == false) { setState(() { sc = true; sc2 = false; }); // print("i: ll"); } else if (notification is ScrollUpdateNotification) { if (pageController2.page != pageController.page amp;amp; sc) { pageController2.position .jumpTo(pageController.position.pixels * 2); } setState(() { page = pageController.page; }); } return true; }, child: PageView.builder( onPageChanged: (pos) { setState(() { currentPage = pos; }); }, physics: BouncingScrollPhysics(), pageSnapping: sc, controller: pageController, itemCount: listOfCharacters.length, itemBuilder: (context, index) { return Container( color: Colors.blueAccent, ); }, ), ), ), Flexible( flex: 2, child: NotificationListenerlt;ScrollNotificationgt;( onNotification: (ScrollNotification notification) { if (notification.depth == 0 amp;amp; notification is UserScrollNotification amp;amp; sc2 == false) { setState(() { // i = 2; sc = false; sc2 = true; }); // print("i: ll"); } else if (notification.depth == 0 amp;amp; notification is ScrollUpdateNotification amp;amp; sc2) { // page = pageController2; if (pageController2.page != pageController.page) { pageController.position .jumpTo(pageController2.position.pixels / 2); } } return true; }, child: PageView.builder( pageSnapping: sc2, controller: pageController2, onPageChanged: (pos) { setState(() { currentPage = pos; }); }, physics: BouncingScrollPhysics(), itemCount: listOfCharacters.length, itemBuilder: (context, index) { return ListView( children: [ Padding( padding: const EdgeInsets.only(bottom: 10.0), child: Text( listOfCharacters[index]['name'], textAlign: TextAlign.center, style: TextStyle(fontSize: 20), ), ), Container( color: cc[index], height: 50, ), Container( color: Colors.red, height: 500, ) ], ); }, ), ), ), ], ), ), ], ), ), ); } } const Listlt;Colorgt; cc = [ Colors.black, Colors.green, Colors.purple, Colors.yellow, Colors.blueAccent ];