Detect widget visibility?

4,373 views
Skip to first unread message

Lee Crocker

unread,
Dec 13, 2018, 3:59:34 PM12/13/18
to Flutter Dev
I have a stateful widget that displays incoming data from a stream. I subscribe in initState() and close in dispose() as usual, and all works fine. When the widget is off-screen, or otherwise not visible, the state continues to update--which works just fine--but I'd rather it didn't, because acquiring the data for its update is somewhat expensive, and I'd rather suspend that when it's not needed and resume when the widget becomes visible again. I've tried using "if (mounted)" in the updater, but that continues to run when the widget is off-screen. Is there any way to detect when the widget is physically visible? 

I suppose I could simply keep track of which page I'm on and only update when those pages containing the widget are active, but that wouldn't handle the case of the widget being scrolled away or covered by a popup.

EthicCoders Apps

unread,
Dec 13, 2018, 4:29:45 PM12/13/18
to l...@ansync.com, flutt...@googlegroups.com
To keep track of the scrolling of the page (and its offset), in one of our project we used: ScrollController...  (This was useful for us to either show or hide the floating button...) 
Below is the code and see if this helps your case to activate or deactivate the subscription:
 
class _HomeViewState extends State<HomeView> {
ScrollController _scrollController = new ScrollController();
....
.......
@override
void initState() {
// TODO: implement initState
super.initState();
..
  initScrollController();
}

initScrollController() {
_scrollController.addListener((){
if(_scrollController.offset > 135.0) {
      ....
setState(() {
makeShareVisible(true, generateShareText(celebrations));
});
}
else {
....
setState(() {
makeShareVisible(false, generateShareText(celebrations));
});
}
});
}


On Fri, Dec 14, 2018 at 2:29 AM Lee Crocker <l...@ansync.com> wrote:
I have a stateful widget that displays incoming data from a stream. I subscribe in initState() and close in dispose() as usual, and all works fine. When the widget is off-screen, or otherwise not visible, the state continues to update--which works just fine--but I'd rather it didn't, because acquiring the data for its update is somewhat expensive, and I'd rather suspend that when it's not needed and resume when the widget becomes visible again. I've tried using "if (mounted)" in the updater, but that continues to run when the widget is off-screen. Is there any way to detect when the widget is physically visible? 

I suppose I could simply keep track of which page I'm on and only update when those pages containing the widget are active, but that wouldn't handle the case of the widget being scrolled away or covered by a popup.

--
You received this message because you are subscribed to the Google Groups "Flutter Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to flutter-dev...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Olaide Nojeem Ekeolere

unread,
Dec 13, 2018, 4:30:53 PM12/13/18
to l...@ansync.com, Flutter Dev
Hi Lee,
  Why not use a StreamBuilder instead of subscribing to the stream yourself? Anyway you can make your widget implement RouteAware like below:

final RouteObserver<PageRoute> routeObserver = new RouteObserver<PageRoute>();

class MyClass extends StatefulWidget{
createState() => _MyClassState();
}
class _MyClassState extends State<MyClass> with RouteAware{
@override
void didChangeDependencies() {
super.didChangeDependencies();
routeObserver.subscribe(this, ModalRoute.of(context));
}

@override
void didPopNext() {
// Covering route was popped off the navigator.
print('Popped A route');
}

@override
void didPushNext() {
// Route was pushed onto navigator and is now topmost route.
print('Pushed A Route');
}

@override
Widget build(BuildContext context) {
// TODO: implement build
return null;
}

}

On Thu, Dec 13, 2018 at 9:59 PM Lee Crocker <l...@ansync.com> wrote:
I have a stateful widget that displays incoming data from a stream. I subscribe in initState() and close in dispose() as usual, and all works fine. When the widget is off-screen, or otherwise not visible, the state continues to update--which works just fine--but I'd rather it didn't, because acquiring the data for its update is somewhat expensive, and I'd rather suspend that when it's not needed and resume when the widget becomes visible again. I've tried using "if (mounted)" in the updater, but that continues to run when the widget is off-screen. Is there any way to detect when the widget is physically visible? 

I suppose I could simply keep track of which page I'm on and only update when those pages containing the widget are active, but that wouldn't handle the case of the widget being scrolled away or covered by a popup.

James Lin

unread,
Dec 13, 2018, 6:43:37 PM12/13/18
to l...@ansync.com, flutt...@googlegroups.com
You might be interested in a VisibilityDetector widget we wrote:

It's not yet available via pub (but we plan to add it there soon).

If you use it, feel free to let me know if you have any questions or if you run into any issues.

- James

On Thu, Dec 13, 2018 at 12:59 PM Lee Crocker <l...@ansync.com> wrote:
I have a stateful widget that displays incoming data from a stream. I subscribe in initState() and close in dispose() as usual, and all works fine. When the widget is off-screen, or otherwise not visible, the state continues to update--which works just fine--but I'd rather it didn't, because acquiring the data for its update is somewhat expensive, and I'd rather suspend that when it's not needed and resume when the widget becomes visible again. I've tried using "if (mounted)" in the updater, but that continues to run when the widget is off-screen. Is there any way to detect when the widget is physically visible? 

I suppose I could simply keep track of which page I'm on and only update when those pages containing the widget are active, but that wouldn't handle the case of the widget being scrolled away or covered by a popup.

Lee Crocker

unread,
Dec 14, 2018, 1:36:43 PM12/14/18
to Flutter Dev

Thanks, all, for the suggestions. The hard part for me now seems to be trapping the Android back button. That pops a page, but does not go through the Navigator, and so doesn't notify the observers, unless I'm missing something.
 
Reply all
Reply to author
Forward
0 new messages