Skip to content

Instantly share code, notes, and snippets.

@Mastersam07
Created July 14, 2024 23:02
Show Gist options
  • Save Mastersam07/1006ce0f98fd8e088fae785c609be274 to your computer and use it in GitHub Desktop.
Save Mastersam07/1006ce0f98fd8e088fae785c609be274 to your computer and use it in GitHub Desktop.
Find scrollables in viewport
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Scrollable Widgets in Viewport'),
),
body: HomeScreen(),
),
);
}
}
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final GlobalKey _key = GlobalKey();
List<Widget> scrollableWidgets = [];
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
findScrollableWidgets();
});
}
void findScrollableWidgets() {
final RenderObject? rootRenderObject =
_key.currentContext?.findRenderObject();
if (rootRenderObject == null) return;
final List<Widget> foundScrollables = [];
void visitChildren(Element element) {
element.visitChildren((child) {
if (child.widget is ScrollView) {
final RenderObject renderObject = child.renderObject!;
if (_isWithinViewport(rootRenderObject as RenderBox, renderObject)) {
foundScrollables.add(child.widget);
}
}
visitChildren(child);
});
}
visitChildren(_key.currentContext as Element);
setState(() {
scrollableWidgets = foundScrollables;
});
}
bool _isWithinViewport(RenderBox viewport, RenderObject renderObject) {
final Size viewportSize = viewport.size;
final Offset viewportOffset = viewport.localToGlobal(Offset.zero);
final Rect viewportRect = viewportOffset & viewportSize;
final Size renderObjectSize = renderObject.paintBounds.size;
final Offset renderObjectOffset =
(renderObject as RenderBox).localToGlobal(Offset.zero);
final Rect renderObjectRect = renderObjectOffset & renderObjectSize;
return viewportRect.overlaps(renderObjectRect);
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Expanded(
child: SingleChildScrollView(
key: _key,
child: Column(
children: [
ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: 20,
itemBuilder: (context, index) {
return ListTile(
title: Text('Item $index'),
);
},
),
GridView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemCount: 20,
itemBuilder: (context, index) {
return Card(
child: Center(child: Text('Card $index')),
);
},
),
],
),
),
),
ElevatedButton(
onPressed: () {
findScrollableWidgets();
print('Found ${scrollableWidgets.length} scrollable widgets');
for (var widget in scrollableWidgets) {
print(widget.runtimeType);
}
},
child: Text('Find Scrollable Widgets'),
),
],
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment