我有一个 SingleChildScrollView,它包含一个可滚动的 TabBar,并且我有一个监听通知的 NotificationListener。
我的问题是我从两个小部件都收到 ScrollNotification,但我不知道如何判断两个小部件中的哪一个触发了通知。
ScrollNotification 包含 BuildContext?上面的评论表明这可以用来确定源,但我不明白如何使用构建上下文来确定我的哪个对象触发了通知。
/// The build context of the widget that fired this notification.
///
/// This can be used to find the scrollable's render objects to determine the
/// size of the viewport, for instance.
final BuildContext? context;
Run Code Online (Sandbox Code Playgroud)
是的,BuildContext可以用于此目的。您可以用来findAncestorWidgetOfExactType查找触发小部件是否具有特定的祖先小部件类型。
例如,我有一个屏幕,有 3 个可滚动的东西: a ListView、 aGridView和水平滚动SingleChildScrollView,如下所示:
在 中NotificationListener,我们可以检查事件的来源,如下所示:
// Cast the `BuildContext` into an `Element`
final element = (notification.context as Element);
// Try to see if the `Element` has an ancestor of type `ListView`, `GridView` or `SingleChildScrollView`.
final listView = element.findAncestorWidgetOfExactType<ListView>();
final gridView = element.findAncestorWidgetOfExactType<GridView>();
final scrollView = element.findAncestorWidgetOfExactType<SingleChildScrollView>();
// One of them should have a non-null value, the other two would be null.
print('listView: $listView');
print('gridView: $gridView');
print('scrollView: $scrollView');
Run Code Online (Sandbox Code Playgroud)
完整示例:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(backgroundColor: Colors.black),
body: NotificationListener(
onNotification: (notification) {
if (notification is ScrollUpdateNotification) {
final element = (notification.context as Element);
final listView = element.findAncestorWidgetOfExactType<ListView>();
final gridView = element.findAncestorWidgetOfExactType<GridView>();
final scrollView =
element.findAncestorWidgetOfExactType<SingleChildScrollView>();
print('listView: $listView');
print('gridView: $gridView');
print('scrollView: $scrollView');
}
return false;
},
child: Column(
children: [
Expanded(
child: ListView.builder(
itemBuilder: (context, index) => ListTile(
title: Text('List View Item $index'),
),
),
),
Expanded(
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemBuilder: (context, index) => Center(
child: Text('Grid View Item $index'),
),
),
),
Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
for (int i = 0; i < 100; i++) FlutterLogo(),
],
),
),
),
],
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1129 次 |
| 最近记录: |