和iOS平台一样右侧那个滚动条怎么显示出来???
来源:10-4 基于GridView实现网格布局【跟着做】
ptlCoder
2019-03-22
写回答
2回答
-
ptlCoder
提问者
2019-03-26
感谢老师的解答,
这里有个demo,可能和iOS系统滚动条更接近一点,
https://inducesmile.com/google-flutter/how-to-show-scroll-indicator-in-listview-in-flutter/
012019-03-26 -
CrazyCodeBoy
2019-03-25
可以参考如下代码实现:
import 'package:flutter/material.dart'; import 'package:flutter/gestures.dart'; void main() => runApp(new MyApp()); class MyApp extends StatelessWidget { //provide the same scrollController for list and draggableScrollbar final ScrollController controller = ScrollController(); @override Widget build(BuildContext context) { return new MaterialApp( theme: new ThemeData( primarySwatch: Colors.blue, ), home: new Scaffold( appBar: new AppBar( title: new Text('Draggable Scroll Bar Demo'), ), //DraggableScrollbar builds Stack with provided Scrollable List of Grid body: new DraggableScrollbar( child: _buildGrid(), heightScrollThumb: 40.0, controller: controller, ), ), ); } Widget _buildGrid() { return GridView.builder( controller: controller,//scrollController is final in this stateless widget gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 5, ), padding: EdgeInsets.zero, itemCount: 1000, itemBuilder: (context, index) { return Container( alignment: Alignment.center, margin: EdgeInsets.all(2.0), color: Colors.grey[300], //I've add index to grid cells to see more clear how it scrolls child: new Center(child: new Text("$index")), ); }, ); } } class DraggableScrollbar extends StatefulWidget { final double heightScrollThumb; final Widget child; final ScrollController controller; DraggableScrollbar({this.heightScrollThumb, this.child, this.controller}); @override _DraggableScrollbarState createState() => new _DraggableScrollbarState(); } class _DraggableScrollbarState extends State<DraggableScrollbar> { //this counts offset for scroll thumb in Vertical axis double _barOffset; //this counts offset for list in Vertical axis double _viewOffset; //variable to track when scrollbar is dragged bool _isDragInProcess; @override void initState() { super.initState(); _barOffset = 0.0; _viewOffset = 0.0; _isDragInProcess = false; } //if list takes 300.0 pixels of height on screen and scrollthumb height is 40.0 //then max bar offset is 260.0 double get barMaxScrollExtent => context.size.height - widget.heightScrollThumb; double get barMinScrollExtent => 0.0; //this is usually lenght (in pixels) of list //if list has 1000 items of 100.0 pixels each, maxScrollExtent is 100,000.0 pixels double get viewMaxScrollExtent => widget.controller.position.maxScrollExtent; //this is usually 0.0 double get viewMinScrollExtent => widget.controller.position.minScrollExtent; double getScrollViewDelta( double barDelta, double barMaxScrollExtent, double viewMaxScrollExtent, ) {//propotion return barDelta * viewMaxScrollExtent / barMaxScrollExtent; } double getBarDelta( double scrollViewDelta, double barMaxScrollExtent, double viewMaxScrollExtent, ) {//propotion return scrollViewDelta * barMaxScrollExtent / viewMaxScrollExtent; } void _onVerticalDragStart(DragStartDetails details) { setState(() { _isDragInProcess = true; }); } void _onVerticalDragEnd(DragEndDetails details) { setState(() { _isDragInProcess = false; }); } void _onVerticalDragUpdate(DragUpdateDetails details) { setState(() { _barOffset += details.delta.dy; if (_barOffset < barMinScrollExtent) { _barOffset = barMinScrollExtent; } if (_barOffset > barMaxScrollExtent) { _barOffset = barMaxScrollExtent; } double viewDelta = getScrollViewDelta( details.delta.dy, barMaxScrollExtent, viewMaxScrollExtent); _viewOffset = widget.controller.position.pixels + viewDelta; if (_viewOffset < widget.controller.position.minScrollExtent) { _viewOffset = widget.controller.position.minScrollExtent; } if (_viewOffset > viewMaxScrollExtent) { _viewOffset = viewMaxScrollExtent; } widget.controller.jumpTo(_viewOffset); }); } //this function process events when scroll controller changes it's position //by scrollController.jumpTo or scrollController.animateTo functions. //It can be when user scrolls, drags scrollbar (see line 139) //or any other manipulation with scrollController outside this widget changePosition(ScrollNotification notification) { //if notification was fired when user drags we don't need to update scrollThumb position if (_isDragInProcess) { return; } setState(() { if (notification is ScrollUpdateNotification) { _barOffset += getBarDelta( notification.scrollDelta, barMaxScrollExtent, viewMaxScrollExtent, ); if (_barOffset < barMinScrollExtent) { _barOffset = barMinScrollExtent; } if (_barOffset > barMaxScrollExtent) { _barOffset = barMaxScrollExtent; } _viewOffset += notification.scrollDelta; if (_viewOffset < widget.controller.position.minScrollExtent) { _viewOffset = widget.controller.position.minScrollExtent; } if (_viewOffset > viewMaxScrollExtent) { _viewOffset = viewMaxScrollExtent; } } }); } @override Widget build(BuildContext context) { return NotificationListener<ScrollNotification>( onNotification: (ScrollNotification notification) { changePosition(notification); }, child: new Stack(children: <Widget>[ widget.child, GestureDetector( //we've add functions for onVerticalDragStart and onVerticalDragEnd //to track when dragging starts and finishes onVerticalDragStart: _onVerticalDragStart, onVerticalDragUpdate: _onVerticalDragUpdate, onVerticalDragEnd: _onVerticalDragEnd, child: Container( alignment: Alignment.topRight, margin: EdgeInsets.only(top: _barOffset), child: _buildScrollThumb())), ])); } Widget _buildScrollThumb() { return new Container( height: widget.heightScrollThumb, width: 20.0, color: Colors.blue, ); } }
012019-03-26
相似问题