Reputation: 3676
So, i have a widget with infinite width (Row) . To fill the widget with items i'm using a Lisview builder with Axis horizontal. I also can use a SingleChildScrollview with axis horizontal and a Row as the child.
If there is a few items, the width of the screen is not filled, so that's great. However, when there is a lot of items, the Listview becomes "scrollable" , and i can scroll to the right to reveal the items.
I would like to know if the list is scrollable (if it overflows). The purpose is to show a little text saying "Scroll to reveal more>>".
I know i can use maths and calculate the items width with the screen width. However... The Listview already knows this, so i was wondering if there was a way of getting access to that information
Upvotes: 8
Views: 6415
Reputation: 702
bool get isScrollable => scrollController.position.extentInside > 0;
Upvotes: 0
Reputation: 652
I created a widget called ScrollCheckerWidget with a controller
property to pass the controller of a scrollable widget and check if it is scrollable in the view. The ScrollCheckerWidget widget has a builder
callback function where you can return a widget and use the isScrollable
boolean from the builder
to check if the widget related to the controller is scrollable or not. Here you have the code:
import 'package:flutter/material.dart';
class ScrollCheckerWidget extends StatefulWidget {
const ScrollCheckerWidget({
Key? key,
required this.controller,
required this.builder,
}) : super(key: key);
final ScrollController controller;
final Widget Function(bool isScrollable) builder;
@override
State<ScrollCheckerWidget> createState() => _ScrollCheckerWidgetState();
}
class _ScrollCheckerWidgetState extends State<ScrollCheckerWidget> {
late final ScrollController _scrollController;
late bool _isScrollable;
@override
void initState() {
_scrollController = widget.controller;
_isScrollable = false;
WidgetsBinding.instance.addPostFrameCallback((_) {
setState(() {
_isScrollable = _scrollController.position.maxScrollExtent > 0;
});
});
super.initState();
}
@override
Widget build(BuildContext context) {
return widget.builder.call(_isScrollable);
}
}
Upvotes: 1
Reputation: 151
I had a similar problem. I found this solution here: Determine Scroll Widget height
Here's my question in case it's helpful: How do you tell if scrolling is not needed in a SingleChildScrollView when the screen is first built?
Solution:
import 'package:flutter/scheduler.dart';
build
method to track whether build
has been called yet:bool buildCalledYet = false;
isScrollable
variable inside the state object but outside of the build
method:bool isScrollable;
build
method:if (!firstBuild) {
firstBuild = true;
SchedulerBinding.instance.addPostFrameCallback((_) {
setState(() {
isScrollable = !(_scrollController.position.maxScrollExtent > 0);
});
});
}
(The purpose of buildCalledYet
is to prevent this code from causing build
to be called over and over again.)
isScrollable
is true
, then show your text.Upvotes: 6
Reputation: 651
In builder:
return NotificationListener(
onNotification: (scrollNotification) {
print("ScrollStartNotification");
// add your logic here
},
child: SingleChildScrollView(...
Am trying to detect exact same thing myself, wrapping SingleChildScrollView with NotificationListener at least gave me a point of reference to start working on this.
Upvotes: 0