簡體   English   中英

Flutter中如何檢測ListView的滾動位置

[英]How to detect scroll position of ListView in Flutter

我正在使用ListView小部件將項目顯示為列表。 在窗口三中,查看的項目必須將中間的項目放在中間。

那么如何在滾動停止時檢測ListView的位置呢?

如何檢測 ListView 滾動停止?

我使用了NotificationListener ,它是一個小部件,用於偵聽在樹上冒泡的通知。 然后使用ScrollEndNotification ,它表示滾動已停止。

對於滾動位置,我使用_scrollController類型為ScrollController

NotificationListener(
  child: ListView(
    controller: _scrollController,
    children: ...
  ),
  onNotification: (t) {
    if (t is ScrollEndNotification) {
      print(_scrollController.position.pixels);
    }
  },
),

majidfathi69 的回答很好,但是您不需要在列表中添加控制器:(當您只想在滾動結束時收到通知時,請將ScrollUpdateNotification更改為ScrollEndNotification 。)

NotificationListener<ScrollUpdateNotification>(
  child: ListView(
    children: ...
  ),
  onNotification: (notification) {
    //How many pixels scrolled from pervious frame
    print(notification.scrollDelta);

    //List scroll position
    print(notification.metrics.pixels);
  },
),

您還可以通過以下步驟實現此功能

import 'package:flutter/material.dart';

class YourPage extends StatefulWidget {
  YourPage({Key key}) : super(key: key);

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

class _YourPageState extends State<YourPage> {

  ScrollController _scrollController;
  double _scrollPosition;

 _scrollListener() {
  setState(() {
   _scrollPosition = _scrollController.position.pixels;
 });
}

@override
void initState() {
  _scrollController = ScrollController();
  _scrollController.addListener(_scrollListener);
  super.initState();
}

 @override
 Widget build(BuildContext context) {
  return Scaffold(
  appBar: AppBar(
    automaticallyImplyLeading: false,
    title: Text('Position $_scrollPosition pixels'),
  ),
  body: Container(
      child: ListView.builder(
    controller: _scrollController,
    itemCount: 200,
    itemBuilder: (context, index) {
      return ListTile(
        leading: Icon(Icons.mood),
        title: Text('Item: $index'),
      );
    },
  )),
);
}
}

在此處輸入圖像描述

NotificationListener現在接受一個使代碼更短的類型參數:)

NotificationListener<ScrollEndNotification>(
  child: ListView(
    controller: _scrollController,
    children: ...
  ),
  onNotification: (notification) {
    print(_scrollController.position.pixels);
    // Return true to cancel the notification bubbling. Return false (or null) to
    // allow the notification to continue to be dispatched to further ancestors.
    return true;
  },
),

如果你想檢測ListView的滾動位置,你可以簡單地使用它;

Scrollable.of(context).position.pixels

除了@seddiq-sorush 回答,你可以將當前位置與_scrollController.position.maxScrollExtent進行比較,看看列表是否在底部

我會說您可以通過以下方式輕松檢測滾動位置

@override
  void initState() {
    super.initState();

    _scrollController = ScrollController();
    _scrollController.addListener(() {
      var _currectScrollPosition = _scrollController.position.pixels;//this is the line
    });
  }

但是如果你要在 addListener() 中調用 setState ; 沒關系,但這會導致重建整個構建(上下文)。 這對於動畫來說不是一個好習慣。

我建議將您的滾動小部件分離成一個單獨的 StatefulWidget ,然后通過調用獲取該小部件的狀態

  _yourScrollableWidgetKey.currentState?.controller.addListener(() {
      //code.......
      setState(() {});
    });

注意:設置一個 GlobalKey,並分配給您的 StatFulWidget。

  final _yourScrollableWidgetKey = GlobalKey<_YourScrollAbleWidget>();
  StackedPositionedAnimated(
    key: _yourScrollableWidgetKey,
  ),

https://coflutter.com/flutter-check-if-the-listview-reaches-the-top-or-the-bottom/來源

如果有人想檢測列表視圖的底部,那么使用這種方式

NotificationListener<ScrollNotification>(
 onNotification: (ScrollNotification notification) {
 if (notification.metrics.atEdge) {
    if (notification.metrics.pixels == 0) {
      print('At top');
    } else {
      print('At bottom');
    }
}
return true;
},
child: ListView.builder(itemBuilder: (BuildContext context) {
  return YourItemWidget;
})
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM