flutter - 当小部件到达屏幕的某个位置时如何触发事件?
问题描述
我希望在小部件位于屏幕的某个位置时触发一个事件。例如,假设我们有一个Container
仍然不可见的 Widget。它位于可滚动的某个位置,Scaffold
其主体的高度足以必须滚动。我们开始滚动,当小部件可见并且到达屏幕中间时,这会触发事件。换句话说,只有当 Widget 处于某个位置时才应该触发事件。也许类似的东西可以用 a 来实现,ScrollController
但我想知道是否有其他方法可以做到这一点。
解决方案
所以我开始了一点研究,我发现我想要的可以用 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,
),
],
),
),
);
}
}
推荐阅读
- javascript - 如何查找带连字符的字符串
- jquery - 根据标签文本选择输入元素
- javascript - 禁止在 Angular 中的(更改)属性之外使用复选框
- ios - 正确对齐 HStack 中的两个 SwiftUI 文本视图
- java - 可以有多个 jpos Q2 实例吗?
- go - 如何在golang中编写一个函数来处理两种类型的输入数据
- jquery - 为什么我在 Django 收到 403 POST 请求错误?
- python - 在 tkinter 中设置错误处理循环
- dom - 我无法访问影子 dom CSS 中的插槽
- javascript - 如何将每个电子邮件地址装箱?[Javascript]