找出ListView中的哪些项目可见

时间:2019-07-12 17:41:06

标签: flutter dart flutter-layout flutter-listview

如何找出visible中当前是invisibleListView的项目?
例如,我在ListView中有100个项目,当我滚动到屏幕或列表顶部时,我想检测出哪些项目从视口中出现或消失。

插图:

enter image description here

2 个答案:

答案 0 :(得分:2)

没有简单的方法可以做到这一点。 Here是同一个问题,但是没有答案。

对此有一个活跃的GitHub issue

该问题中有多种解决方案。 Gist的功能需要rect_getter package
另外,您可以看看this proposal

TL; DR

如果您正在寻找一种简便的查找方法,则尚未实现。但是,有解决方案,就像我上面提到的那样。

答案 1 :(得分:0)

我不确定我是否理解正确,请尝试

import 'dart:collection';
import 'dart:math' as math;

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(title: Text("Test")),
        body: Content(),
      ),
    );
  }
}

class Content extends StatefulWidget {
  @override
  _ContentState createState() => _ContentState();
}

class _ContentState extends State<Content> {
  final Set<int> _indexes = SplayTreeSet();
  final ScrollController _scrollController = ScrollController();

  @override
  void initState() {
    super.initState();
    _scrollController.addListener(() => _doStuff());
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: 100,
      controller: _scrollController,
      cacheExtent: 0, // some kind of brown colored magic is here
      itemBuilder: (context, index) => YourListItem(index: index, indexes: _indexes),
    );
  }

  void _doStuff() async {
    print('$_indexes');
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }
}

class YourListItem extends StatefulWidget {
  final int index;
  final Set<int> indexes;

  YourListItem({@required this.index, @required this.indexes});

  @override
  _YourListItemState createState() => _YourListItemState();
}

class _YourListItemState extends State<YourListItem> {
  @override
  Widget build(BuildContext context) {
    // here is build your list item
    return Container(
      padding: const EdgeInsets.all(48),
      color: Color((math.Random().nextDouble() * 0xFFFFFF).toInt() << 0).withOpacity(0.5),
      child: Text('item ${widget.index}'),
    );
  }

  @override
  void deactivate() {
    widget.indexes.add(widget.index);
    super.deactivate();
  }

  @override
  void didChangeDependencies() {
    widget.indexes.remove(widget.index);
    super.didChangeDependencies();
  }
}

此代码将打印停用列表项的索引

这里也可以添加stream.distinct()以避免重复,但这超出了这个问题的范围