Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Q: onExpanded() callback? #44

Open
TomTom101 opened this issue Jan 30, 2020 · 13 comments
Open

Q: onExpanded() callback? #44

TomTom101 opened this issue Jan 30, 2020 · 13 comments

Comments

@TomTom101
Copy link

Is there some kind of callback to when an ExpandablePanel was expanded/toggled? An onExpanded() prop would be ideal for my use case.
Thanks!

@aryzhov
Copy link
Owner

aryzhov commented Feb 6, 2020

I will add that in the next release. Thank you for reporting.

@pawlowskim
Copy link

@TomTom101 You can pass controller and add listener to controller. Then in onChange function check _controller.expanded flag

@TomTom101
Copy link
Author

What kind of controller? Can you give a quick example? Thanks!

@pawlowskim
Copy link

class MyItem extends StatefulWidget {
  final ItemModel _item;
  final bool expanded;

  const MyItem(this._item, {this.expanded = false});

  @override
  _MyItemState createState() => _MyItemState();
}

class _MyItemState extends State<MyItem> {
  ExpandableController _controller;

  @override
  void initState() {
    super.initState();
    _controller = new ExpandableController(initialExpanded: widget.expanded);
    _controller.addListener(_onToggle);
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  void didUpdateWidget(MyItem oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.expanded) {
      _controller.expanded = true;
    }
  }
  
  _onToggle(){
    print("Is expanded: ${_controller.expanded}");
  }

  @override
  Widget build(BuildContext context) =>
      ExpandableTheme(
          data: ExpandableThemeData(
              headerAlignment: ExpandablePanelHeaderAlignment.center),
          child: ExpandablePanel(
              controller: _controller,
              header: Text(widget._item.title, style: Themes.baseRegularGrey),
              expanded: Text(widget._item.content)));
}

@raindy29
Copy link

raindy29 commented Mar 11, 2020

ExpandableController not good idea for multi panel,
onExpanded on every panel can be solved

@MostHated
Copy link

Hey there, I have a question related to this. I am using the Provider package and I was trying to make it so that when an item is expanded it changes the parent's flex value for it's width.

Below is essentially how I have it set up, but I keep getting the following error (Below the code): I am guessing that it is because it is trying to change the value/expand the parent but the expanding widget is animating to actually expand still (or something along these lines). Is there a way to know when it has completed the expanding, or to do what I am trying to do before the expanding begins? If there are any recommendations, I would greatly appreciate it.

Thanks,
-MH

This is part of the Provider notifier I am using for this.

class ChangeLogDataProvider with ChangeNotifier {
  bool _changeLogExpanded = false;

  void setExpanded(bool expand) {
    _changeLogExpanded = expand;
    notifyListeners();
  }

  bool get isExpanded => _changeLogExpanded;

This is part of the widget display for the expanding items where I am setting the expansion value based on the controller.expanded value.

   final changeLogData = Provider.of<ChangeLogDataProvider>(context);

   builder: (context, collapsed, expanded) {
     var controller = ExpandableController.of(context);
     controller.expanded ? changeLogData.setExpanded(true) : changeLogData.setExpanded(false);
    }

This is part of the parent widget in which I am trying to set the flex value based on the value in the Provider notifier, which was set from the controller.expanded value above.

   final changeLogData = Provider.of<ChangeLogDataProvider>(context);

   Flexible(
     flex: (changeLogData.isExpanded) ? 3 : 1,
       child: AnimatedSize(
       curve: Curves.easeIn,
       duration: new Duration(milliseconds: 300),
       vsync: this,
       child: ChangeLogList(),
      )),
The following assertion was thrown while dispatching notifications for ChangeLogDataProvider:
setState() or markNeedsBuild() called during build.

This _InheritedProviderScope<ChangeLogDataProvider> widget cannot be marked as needing to build because the framework is already in the process of building widgets.  A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
The widget on which setState() or markNeedsBuild() was called was: _InheritedProviderScope<ChangeLogDataProvider>
  value: Instance of 'ChangeLogDataProvider'
  listening to value
The widget which was currently being built when the offending call was made was: ExpandablePanel
  dirty
  dependencies: [_ExpandableControllerNotifier]
When the exception was thrown, this was the stack: 
#0      Element.markNeedsBuild.<anonymous closure> (package:flutter/src/widgets/framework.dart:4171:11)
#1      Element.markNeedsBuild (package:flutter/src/widgets/framework.dart:4186:6)
#2      _InheritedProviderScopeElement.markNeedsNotifyDependents (package:provider/src/inherited_provider.dart:426:5)
#3      ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:207:21)
#4      ChangeLogDataProvider.setWidth (package:searcher_installer_go/data/provider/changelog_provider.dart:20:5)
...
The ChangeLogDataProvider sending notification was: Instance of 'ChangeLogDataProvider'
════════════════════════════════════════════════════════════════════════════════════════════════════

@AdnanAli285
Copy link

Hi @aryzhov, can you provide an idea when this feature is coming up,

@Ceschref
Copy link

I will add that in the next release. Thank you for reporting.

it is November now but it is still not resolved :(

@alemosa
Copy link

alemosa commented Jan 30, 2021

Any news on this feature?

@Cybernetics354
Copy link

I have create a PR about this because i need this functionality too. i can achieve this with listen to ExpandableController but when it comes to List, i think that's a bad approach,.

#93

@aryzhov
Copy link
Owner

aryzhov commented Mar 29, 2021 via email

@sezimik
Copy link

sezimik commented May 25, 2021

I just wanted to let you know that without this callback this awesome library is useless. I spent a few hours to implement it in my code and now I have to migrate to flutter's Expansion list because this library is missing the callback. This callback is so essential and obvious that I thought you had implemented it when I red your Pub.dev page but then I realized I only wasted a few hours.
Thank you.

@ramvdixit
Copy link

As @TomTom101 suggested, this can be achieved with the controller addListener callback.

class _MyPageState extends State<MyPage> {
...
final ExpandableController _infoPanelController = ExpandableController(initialExpanded: false);
...

@override
  void initState() {
   _infoPanelController.addListener(() {
      if (_infoPanelController.expanded) {
        setState(() {
          ...
        });
      } else {
        setState(() {
          ...
        });
      }
    });
    super.initState();
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests