Ani*_*lil 6 listview alphabet flutter
如何在颤动中获取手指移动事件,例如“android 中的 recyclerview 字母索引”检查示例图像。
我创建了一个定位字母索引列表视图,但在 DragUpdate 中找不到当前索引。
var alphabet = ["#","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
new Positioned(
top: .0,
left: 1,
bottom: 10,
width: 55,
child: Material(
borderRadius: BorderRadius.circular(15.0),
elevation: 10.0,
child: ListView.builder(
itemCount: alphabet.length,
itemBuilder: (BuildContext context, int index) {
return new GestureDetector(
onVerticalDragUpdate:
(DragUpdateDetails detail) {
setState(() {
_barOffset += detail.delta.dy;
});
print("$detail");
print("Update ${alphabet[index]}");
},
onVerticalDragStart: (DragStartDetails detail) {
print("onVerticalDragStart");
print("Start ${alphabet[index]}");
},
onVerticalDragEnd: (DragEndDetails detail) {
print("onVerticalDragEnd");
print("End ${alphabet[index]}");
},
onTap: () => print(alphabet[index]),
child: new Container(
margin: EdgeInsets.only(
left: 20.0, right: 10.0, top: 6.5),
height: 15.0,
child: new Text('${alphabet[index]}'),
));
}),
),
Run Code Online (Sandbox Code Playgroud)
要有这样的东西:
为了解决这个问题,您需要创建一个自定义小部件,该小部件将返回一个LayoutBuilderwho 包含一个Stackwho 包含一个ListView在第一层和一个Container在第二层(作为滚动条)的右侧(将滚动条放在右侧添加alignment: Alignment.topRight到您的Stack)。
要移动滚动条,请添加 aGestureDetector并捕获onVerticalDragUpdate添加,请使用自定义属性_offsetContainer,您将添加details.delta.dy(从事件中)以使滚动条向下和向上移动。
之后,您需要添加一个ScrollController来ListView控制它的垂直移动(作为controller属性)。
好的,现在您需要了解多个内容才能继续:
ListViewListView(我们称之为_itemsizeheight)现在要达到的目标是移动ListView列表中以所选字母开头的第一项。
为此,你需要一些数学知识和一些技巧。
要计算您的ListView身高,您需要获取身体高度并删除其他小部件的高度。但为了简化,我们会说你ListView占据了所有的身高。那么它对应contrainsts.biggest.height(感谢LayoutBuilder)。
要计算滚动条高度,您可以有效地将主体高度除以字母表数组中的字母数。
_heightscroller = contrainsts.biggest.height / _alphabet.length;
我们首先将使用小部件使滚动条显示字母索引Text。然后将一个Text小部件添加到您的控制器,并_text在自定义小部件中添加一个属性,以允许您使用该功能更改它setState。
在你的onVerticalDragUpdate你有_offset与你的滚动条位置相对应的值。然后您需要进行一个“简单”计算来找到它对应的字母数组的女巫索引。
_text = _alphabet[((_offsetContainer / _heightscroller) % _alphabet.length).round()];
Run Code Online (Sandbox Code Playgroud)
现在您知道了这封信,那么移动您的ListView. 首先获取列表中与所选字母对应的第一个元素的索引。
例子:
var index = 0;
for (var i = 0; i < widget.items.length; i++) {
if (widget.items[i].toString().trim().length > 0 &&
widget.items[i].toString().trim().toUpperCase()[0] ==
_text.toString().toUpperCase()[0]) {
index = i;
break;
}
}
Run Code Online (Sandbox Code Playgroud)
现在您已经有了索引,只需使用您的ScrollController来移动您的ListView.
_scrollController.animateTo(index * _itemsizeheight,
duration: new Duration(milliseconds: 500),
curve: Curves.ease);
Run Code Online (Sandbox Code Playgroud)
好的,现在它可以工作了,但是我们也需要移动滚动条不是吗?V我的意思是,当ListView将显示我的信件项目时,我不希望它留在信件上 A。
这个怎么做 ?
在您的 init 函数中,您可以设置ScrollController添加
_scrollController.addListener(onscrolllistview);以了解用户何时会直接在ListView.
在您的onscrolllistview函数中,您需要一些计算来显示第一个项目和最后一个项目。
var indexFirst = ((_scrollController.offset / _itemsizeheight) % widget.items.length).floor();
var indexLast = ((((_heightscroller * _alphabet.length) / _itemsizeheight).floor() + indexFirst) - 1) % widget.items.length;
Run Code Online (Sandbox Code Playgroud)
现在完美了,您可以轻松地知道需要在滚动条上显示的女巫字母,然后知道它需要在哪里(更改其偏移量)。
var i = _alphabet.indexOf(fletter);
if (i != -1) {
setState(() {
_text = _alphabet[i];
_offsetContainer = i * _heightscroller;
});
Run Code Online (Sandbox Code Playgroud)
varfletter将取决于滚动的方向。
如果你往下走,那就是:
var fletter = widget.items[indexLast].toString().toUpperCase()[0];
如果你向上走的话会是:
var fletter = widget.items[indexFirst].toString().toUpperCase()[0];
好的,现在如果您输入 a,debugPrint您将可以看到该onscrolllistview函数始终被调用,即使我们使用滚动条也是如此。这是个问题。那么如何解决呢?
当所有动画完成时,您需要知道何时完成移动。
然后只需_animationcounter在您的类中添加一个属性即可。当您移动滚动条时,您将增加它,并在一个动画完成时减少它。像这样:
for (var i = 0; i < widget.items.length; i++) {
if (widget.items[i].toString().trim().length > 0 &&
widget.items[i].toString().trim().toUpperCase()[0] ==
_text.toString().toUpperCase()[0]) {
_animationcounter++;
_scrollController.animateTo(i * _itemsizeheight,
duration: new Duration(milliseconds: 500),
curve: Curves.ease) .then((x) => {_animationcounter--});
break;
}
}
Run Code Online (Sandbox Code Playgroud)
onscrolllistview现在只需围绕您的滚动条移动代码
if (_animationcounter == 0) {/*...your code...*/}
Run Code Online (Sandbox Code Playgroud)
你需要照顾好自己,_offsetContainer不要越界。你可以这样做,例如:
if ((_offsetContainer + details.delta.dy) >= 0 &&
(_offsetContainer + details.delta.dy) <=
(context.size.height - _heightscroller)) {
_offsetContainer += details.delta.dy;
}
Run Code Online (Sandbox Code Playgroud)
该解决方案可能可以优化(不发送多个动画,添加 var 减少计算)。您可以在这里找到完整的实现: AtoZscrollflutter
| 归档时间: |
|
| 查看次数: |
8369 次 |
| 最近记录: |