【问题标题】:How to trigger event when a widget reaches certain position of the screen?当小部件到达屏幕的某个位置时如何触发事件?
【发布时间】:2021-02-06 02:39:23
【问题描述】:

我希望在小部件位于屏幕的某个位置时触发一个事件。例如,假设我们有一个仍然不可见的Container 小部件。它位于可滚动的Scaffold 的某个位置,其主体的高度足以必须滚动。我们开始滚动,当小部件可见并且到达屏幕中间时,这会触发事件。换句话说,只有当 Widget 处于某个位置时才应该触发事件。使用ScrollController 或许可以实现类似的效果,但我想知道是否还有其他方法。

【问题讨论】:

  • 你的意思是当小部件在列表中可见时你想触发一个函数?
  • 我想是的。只是为了确定,“列表”是什么意思?
  • 但不仅可见,而且“在屏幕上的某个位置”
  • 对于某些位置不确定,但为了可见性,您可以使用可见性检测器小部件
  • 太棒了。这已经是很好的信息了。检查出来。

标签: flutter


【解决方案1】:

所以我开始了一些研究,我发现我想要的可以通过 RenderBox 对象来实现。通过使用它们,您可以获得大小(Size 类型)或位置(Offset 类型)。一旦拥有它们,就很容易触发事件。在这种情况下,我做了一个简单的示例,仅当 Container 的位置超过 y 轴上的给定偏移量时才打印语句(例如,屏幕高度的特定百分比,您可以使用 MediaQuery.of(context).size.height 获得) .我将限制设置为屏幕高度的 75%。按下FloatingActionButton 时会调用该事件。如果您要对其进行测试,请滚动一点,然后按下按钮。再次滚动,然后再次检查,依此类推。您会看到超过限制时触发事件。

我在以下文章的帮助下实现了这一点:https://medium.com/@diegoveloper/flutter-widget-size-and-position-b0a9ffed9407

这是我的例子:

import 'package:flutter/material.dart';

class Example extends StatefulWidget {
  @override
  _ExampleState createState() => _ExampleState();
}

class _ExampleState extends State<Example> {
  GlobalKey _keyRed = GlobalKey();
  GlobalKey _keyPurple = GlobalKey();
  GlobalKey _keyGreen = GlobalKey();
  Offset positionGreen;

  _getSizes(){
    RenderBox renderBoxRed = _keyRed.currentContext.findRenderObject();
    Size sizeRed = renderBoxRed.size;
    print("red size is: $sizeRed");

    RenderBox renderBoxPurple = _keyRed.currentContext.findRenderObject();
    Size sizePurple = renderBoxPurple.size;
    print("purple size is: $sizePurple");


    RenderBox renderBoxGreen = _keyGreen.currentContext.findRenderObject();
    Size sizeGreen = renderBoxGreen.size;
    print("green size is: $sizeGreen");
  }

  _getPositions(){
    final RenderBox renderBoxRed = _keyRed.currentContext.findRenderObject();
    final positionRed = renderBoxRed.localToGlobal(Offset.zero);
    print("red position is: $positionRed");

    final RenderBox renderBoxPurple = _keyPurple.currentContext.findRenderObject();
    final positionPurple = renderBoxPurple.localToGlobal(Offset.zero);
    print("purple position is: $positionPurple");

    final RenderBox renderBoxGreen = _keyGreen.currentContext.findRenderObject();
    positionGreen = renderBoxGreen.localToGlobal(Offset.zero);
    print("green position is: $positionGreen");
  }


  @override
  Widget build(BuildContext context) {
    double limit = MediaQuery.of(context).size.height*.75;

    return Scaffold(
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      floatingActionButton: FloatingActionButton(
        backgroundColor: Colors.orange,
        onPressed: (){
          _getSizes();
          _getPositions();

          print("\npositionGreen in dy is ${positionGreen.dy} and limit is $limit");

          if(positionGreen.dy > limit){
            print("screen resizes");
          } else {
            print("screen doesn't resize");
          }

        },
      ),
      body: SingleChildScrollView(
        child: Column(
          children: [
            Container(
              height: 400,
              key: _keyRed,
            color: Colors.red,
            ),
            Container(
              height: 600,
              key: _keyPurple,
              color: Colors.purple,
            ),
            Container(
              height: 800,
              key: _keyGreen,
              color: Colors.green,
            ),
          ],
        ),
      ),
    );
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多