Created
August 10, 2018 03:58
-
-
Save debuggerx01/b8ef756ee02b3eb82ec3702f14ba94e6 to your computer and use it in GitHub Desktop.
JumpToIndexDemoForFlutter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:async'; | |
import 'package:flutter/material.dart'; | |
import 'package:rect_getter/rect_getter.dart'; | |
void main() => runApp(new MyApp()); | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return new MaterialApp( | |
title: 'Flutter Demo', | |
theme: new ThemeData( | |
primarySwatch: Colors.blue, | |
), | |
home: new MyHomePage(title: 'Flutter Demo Home Page'), | |
); | |
} | |
} | |
class MyHomePage extends StatefulWidget { | |
MyHomePage({Key key, this.title}) : super(key: key); | |
final String title; | |
@override | |
_MyHomePageState createState() => new _MyHomePageState(); | |
} | |
class _MyHomePageState extends State<MyHomePage> { | |
var _keys = {}; | |
@override | |
Widget build(BuildContext context) { | |
/// 给整个ListView设置Rect信息获取能力 | |
var listViewKey = RectGetter.createGlobalKey(); | |
var _ctl = new ScrollController(); | |
var listView = RectGetter( | |
key: listViewKey, | |
child: ListView.builder( | |
controller: _ctl, | |
itemCount: 1000, | |
itemBuilder: (BuildContext context, int index) { | |
print('build : $index'); | |
/// 给每个build出来的item设置Rect信息获取能力 | |
/// 并将用于获取Rect的key及index存入map中备用 | |
_keys[index] = RectGetter.createGlobalKey(); | |
return RectGetter( | |
key: _keys[index], | |
child: Container( | |
color: Colors.primaries[index % Colors.primaries.length], | |
child: SizedBox( | |
width: 100.0, | |
height: 50.0 + ((27 * index) % 15) * 3.14, | |
child: Center( | |
child: Text('$index'), | |
), | |
), | |
), | |
); | |
}, | |
), | |
); | |
var _textCtl = TextEditingController( | |
text: '0', | |
); | |
List<int> getVisible() { | |
/// 先获取整个ListView的rect信息,然后遍历map | |
/// 利用map中的key获取每个item的rect,如果该rect与ListView的rect存在交集 | |
/// 则将对应的index加入到返回的index集合中 | |
var rect = RectGetter.getRectFromKey(listViewKey); | |
var _items = <int>[]; | |
_keys.forEach((index, key) { | |
var itemRect = RectGetter.getRectFromKey(key); | |
if (itemRect != null && !(itemRect.top > rect.bottom || itemRect.bottom < rect.top)) _items.add(index); | |
}); | |
/// 这个集合中存的就是当前处于显示状态的所有item的index | |
return _items; | |
} | |
void scrollLoop(int target, Rect listRect) { | |
var first = getVisible().first; | |
bool direction = first < target; | |
Rect _rect; | |
if (_keys.containsKey(target)) _rect = RectGetter.getRectFromKey(_keys[target]); | |
if (_rect == null || (direction ? _rect.bottom < listRect.top : _rect.top > listRect.bottom)) { | |
var offset = _ctl.offset + (direction ? listRect.height / 2 : -listRect.height / 2); | |
offset = offset < 0.0 ? 0.0 : offset; | |
offset = offset > _ctl.position.maxScrollExtent ? _ctl.position.maxScrollExtent : offset; | |
_ctl.jumpTo(offset); | |
Timer(Duration.zero, () { | |
scrollLoop(target, listRect); | |
}); | |
return; | |
} | |
_ctl.jumpTo(_ctl.offset + _rect.top - listRect.top); | |
} | |
void jumpTo(int target) { | |
var visible = getVisible(); | |
if (visible.contains(target)) return; | |
var listRect = RectGetter.getRectFromKey(listViewKey); | |
scrollLoop(target, listRect); | |
} | |
return new Scaffold( | |
appBar: new AppBar( | |
title: new Text(widget.title), | |
), | |
body: Column( | |
mainAxisAlignment: MainAxisAlignment.start, | |
children: <Widget>[ | |
Expanded( | |
child: NotificationListener<ScrollUpdateNotification>( | |
onNotification: (notification) { | |
getVisible(); | |
return true; | |
}, | |
child: listView, | |
), | |
), | |
Row( | |
mainAxisAlignment: MainAxisAlignment.spaceEvenly, | |
children: <Widget>[ | |
SizedBox( | |
width: 100.0, | |
height: 50.0, | |
child: TextField( | |
controller: _textCtl, | |
), | |
), | |
FlatButton( | |
onPressed: () { | |
print('${_textCtl.text}'); | |
jumpTo(int.parse(_textCtl.text)); | |
}, | |
child: Text('JUMP'), | |
) | |
], | |
), | |
], | |
), | |
); | |
} | |
} | |
// 作者:debuggerx | |
// 链接:https://juejin.im/post/5b6375f8e51d45190f4af4c2 | |
// 来源:掘金 | |
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment