imujtaba8488 / package_im_stepper

A growing collection of beautiful, easy to use, stepper and page indicator widgets.
https://pub.dev/packages/im_stepper
BSD 3-Clause "New" or "Revised" License
148 stars 65 forks source link

How to Recall initState method from Back action #18

Closed rrifafauzikomara closed 3 years ago

rrifafauzikomara commented 3 years ago

I have 5 Screen (Page 1, Page 2, Page 3, Page 4, Page 5) and Main Screen (This is the root for handler stepper).

And then I have flowed like this (next): Page 1 -> Page 2 -> Page 3 -> Page 4 -> Page 5 => This is will execute / run / call initState method.

But how if we back from Page 5 to Page 1? Page 5 -> Page 4 -> Page 3 -> Page 2 -> Page 1 => The initState method is not run again from back.

Sample Code:

class _ProposalAddScreenState extends State<ProposalAddScreen> {
  ...

  static const _defaultTextCount = '1/-';
  int _currentStep = 0;
  int _countStep = 5;
  String _textButtonNext = Modular.get<LanguageKeys>().next.tr();
  String _textCount = _defaultTextCount;
  bool _firstPage = true;

  ...

  void _back() {
    // How to recall initState if back to prev Page?
    if (_currentStep == FlagPageProposal.dataInsurance) {
      setState(() {
        _currentStep--;
        _textCount = _defaultTextCount;
        _firstPage = true;
      });
    } else {
      setState(() {
        _currentStep--;
        _textCount = '${_currentStep + 1}/$_countStep';
        _textButtonNext = _languageKeys.next.tr();
      });
    }
  }

  void _validate(bool isFromNextButton) {
   .....
  }

  ...

  @override
  void initState() {
    super.initState();
    ...
  }

  @override
  Widget build(BuildContext context) {
    return MultiBlocListener(
      listeners: [
        ...
      ],
      child: Scaffold(
        key: _scaffoldGlobalKey,
        backgroundColor: _colorPalettes.white,
        appBar: CustomAppBar(
          ...
        ),
        body: Stack(
          children: [
            Padding(
              padding: EdgeInsets.only(left: 16.0, bottom: 16.0, right: 16.0),
              child: Column(
                children: [
                  Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      DotStepper(
                        dotCount: _countStep,
                        activeStep: _currentStep,
                        dotRadius: 6,
                        shape: Shape.circle,
                        spacing: 5,
                        indicator: Indicator.worm,
                        onDotTapped: (tappedDotIndex) {
                          setState(() {
                            _currentStep = tappedDotIndex;
                          });
                        },
                        fixedDotDecoration: FixedDotDecoration(
                            color: Colors.transparent,
                            strokeColor: _colorPalettes.accentColor,
                            strokeWidth: 1),
                        indicatorDecoration: IndicatorDecoration(
                          color: _colorPalettes.accentColor,
                        ),
                      ),
                      Padding(
                        padding: EdgeInsets.only(left: 8.0),
                        child: Text(
                          _textCount,
                          style: textNormalColor(_colorPalettes.accentColor),
                        ),
                      ),
                    ],
                  ),
                  Expanded(
                    child: _page(),
                  ),
                ],
              ),
            ),
            Align(
              alignment: Alignment.bottomCenter,
              child: Row(
                children: [_previousButton(), _nextButton()],
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _page() {
    if (_currentStep == FlagPageProposal.dataPersonal) {
      return Page1();
    } else if (_currentStep == FlagPageProposal.dataInsurance) {
      return Page2();
    } else if (_currentStep == FlagPageProposal.fund) {
      return Page3();
    } else if (_currentStep == FlagPageProposal.topup) {
      return Page4();
    } else if (_currentStep == FlagPageProposal.rider) {
      return Page5();
    } else {
      return SizedBox();
    }
  }

  Widget _previousButton() {
    return Expanded(
      child: SquareButton(
        text: _languageKeys.back.tr(),
        color: _colorPalettes.accentColor,
        onPressed: _firstPage ? null : () => _back(),
      ),
    );
  }

  Widget _nextButton() {
    return Expanded(
      child: SquareButton(
        text: _textButtonNext,
        onPressed: () => _validate(true),
      ),
    );
  }
}
imujtaba8488 commented 3 years ago

Hi Rifat,

initState() method only runs once i.e. at the beginning of your StatefulWidget. I don't see a reason in your above code, why you want to run the initState() method again. I fail to understand what exactly you're trying to accomplish. I suggest, please provide me with your WhatsApp contact, so that I can try to understand your requirement and assist you further.

Regards Mujtaba

rrifafauzikomara commented 3 years ago

Hi @imujtaba8488

Yeah I know that initState() method only runs once when the StatefulWidget is run. But the main reason why I need to execute initState() from back it's because I have a function on that like this:

initState() {
 if (isFromEdit) {
     // my function to select the data from local database
  }
}

And then on the next button I also have a function to save data to the local database. So, If I go from Page 1 to Page 2, it's mean will save data in the Page 1 to the local database, and then when I back from the Page 2 to the Page 1, it's should execute initState because I have a function to fetch data and then the data should showed on the widget on build method.

imujtaba8488 commented 3 years ago

I believe that is in no way related to an issue with the im_stepper, hence closing it. However, as a workaround to your problem, I suggest moving the isFromEdit to didUpdateDependency()/didUpdateWidget() or thebuild()depending upon your requirement. However, moving to didUpdateDependency()/build()might be expensive, since they are called frequently/randomly by the Flutter engine.