【问题标题】:Flutter: Jump to specific item by item data in ListView.builderFlutter:在 ListView.builder 中逐项跳转到特定数据
【发布时间】:2022-07-20 09:24:54
【问题描述】:

ListView中可以逐项跳转到具体数据吗?

class Test extends StatelessWidget {
  Test({Key? key}) : super(key: key);

  final _list = <String>[
    "INFWARS_CH01_EP01",
    "INFWARS_CH01_EP02",
    "INFWARS_CH01_EP03",
    "INFWARS_CH01_EP04",
    "INFWARS_CH01_EP05",
  ];

  void _scrollToItem() {
    final specificItem = "INFWARS_CH01_EP04";
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView.builder(
        itemCount: _list.length,
        itemBuilder: (context, index) {
          final data = _list[index];
          return Text(data);
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => _scrollToItem(),
      ),
    );
  }
}

如您所见,我想使用_scrollToItem函数not by index or by position,通过特定数据"INFWARS_CH01_EP04"跳转到ListView中的特定项目。

所以INFWARS_CH01_EP04 的 ListView 项目将位于顶部(滚动)。目前在顶部的是INFWARS_CH01_EP01

有可能吗?

【问题讨论】:

  • 我不确定你到底想要什么,但我认为你可以做 data.contain('INFWARS_CH01_EP04') ? this : 或者在这里做点别的事情
  • 我想jump in/scroll toListView.builder中的特定项目按项目数据("INFWARS_CH01_EP04"
  • 我更新有问题,请看

标签: flutter listview scroll jump-list


【解决方案1】:

我使用这个包修复它:https://pub.dev/packages/scroll_to_index

因此您可以在 ListView 中按索引/按项目数据滚动/跳转到特定项目。

class Test extends StatelessWidget {
  Test({Key? key}) : super(key: key);
  AutoScrollController _scrollController = AutoScrollController();

  final _list = <String>[
    "INFWARS_CH01_EP01",
    "INFWARS_CH01_EP02",
    "INFWARS_CH01_EP03",
    "INFWARS_CH01_EP04",
  ];

  void _scrollToItem() async {
    final specificItem = "INFWARS_CH01_EP04";
    final index = _list.indexOf(specificItem);
    await _scrollController.scrollToIndex(
      index,
      preferPosition: AutoScrollPosition.begin,
    );
    await _scrollController.highlight(index);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView.builder(
        controller: _scrollController,
        itemCount: _list.length,
        itemBuilder: (context, index) {
          final data = _list[index];
          return AutoScrollTag(
              key: ValueKey(index),
              controller: _scrollController,
              index: index,
              child: Text(data),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => _scrollToItem(),
      ),
    );
  }
}

【讨论】:

    【解决方案2】:

    要滚动到特定项目,您可以:

    1. 使用indexOf() 方法查找特定项目:

    2. 使用scrollable_positioned_list 包滚动到该项目。

    这是一个完整的工作示例:

    class Test extends StatelessWidget {
      Test({Key? key}) : super(key: key);
      ItemScrollController _scrollController = ItemScrollController();
    
      final _list = <String>[
        "INFWARS_CH01_EP01",
        "INFWARS_CH01_EP02",
        "INFWARS_CH01_EP03",
        "INFWARS_CH01_EP04",
      ];
    
      void _scrollToItem() {
        final specificItem = "INFWARS_CH01_EP04";
        _scrollController.jumpTo(index: _list.indexOf(specificItem));
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: ScrollablePositionedList.builder(
            itemScrollController: _scrollController,
            itemCount: _list.length,
            itemBuilder: (context, index) {
              final data = _list[index];
              return Text(data);
            },
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () => _scrollToItem(),
          ),
        );
      }
    }
    

    另见:flutter ListView scroll to index not available

    【讨论】:

    • 感谢您的回答,但我需要使用 ListView.builder 而不是使用 ScrollablePositionedList.builder。有可能吗?
    • @RRifaFauziKomara 请参阅我的答案中提供的链接。这是最好的方法。为什么你需要它成为ListView?有什么区别?
    • 就像我的问题一样,不需要scroll by index or position,我需要scroll by item content (ex: INFWARS_CH01_EP04)。因为要显示列表数据我使用这个包:pub.dev/packages/inview_notifier_list
    【解决方案3】:

    您可以使用flutter_scrollview_observer lib 来实现您想要的功能,而无需侵入

    正常创建并使用ScrollController的实例。

    ScrollController scrollController = ScrollController();
    
    ListView _buildListView() {
      return ListView.separated(
        controller: scrollController,
        ...
      );
    }
    

    创建 ListObserverController 的实例,将其传递给 ListViewObserver

    ListObserverController observerController = ListObserverController(controller: scrollController);
    
    ListViewObserver(
      controller: observerController,
      child: _buildListView(),
      ...
    )
    

    现在可以滚动到指定的索引位置

    // Find the specific item index.
    final targetIndex = _list.indexOf(specificItem);
    
    // Jump to the specified index position without animation.
    observerController.jumpTo(index: targetIndex)
    
    // Jump to the specified index position with animation.
    observerController.animateTo(
      index: targetIndex,
      duration: const Duration(milliseconds: 250),
      curve: Curves.ease,
    );
    

    【讨论】:

      猜你喜欢
      • 2019-10-29
      • 1970-01-01
      • 2020-09-18
      • 1970-01-01
      • 2021-12-26
      • 2021-01-19
      • 2020-05-01
      • 2020-05-19
      • 2021-04-30
      相关资源
      最近更新 更多