简体   繁体   中英

How to scroll to a position in Flutter Stepper?

I'm using the vertical type stepper, where I have multiple steps (over 20), I want the step with the isActive property to appear at the beginning, but I can still scroll up to see the previous ones.


Stepper(
                  key: key_1,
                  physics: ClampingScrollPhysics(),
                  onStepTapped: (step) => goTo(step),
                  currentStep: currentStep,
                  controlsBuilder: (BuildContext context,
                      {VoidCallback onStepContinue,
                        VoidCallback onStepCancel}) {
                    return Row(
                      children: <Widget>[
                        Container(
                          child: null,
                        ),
                        Container(
                          child: null,
                        ),
                      ],
                    );
                  },
                  steps: steps)

Example: if step 2 is active, I want it to appear at the beginning and that step 1 when scrolling above can see it, but visually the one that is at the beginning is step 2 enter image description here

In my case what I did was a modification in the Stepper widget.

Declare the scrollController variable, as follows:

const Stepper({
    Key key,
    @required this.steps,
    this.physics,
    this.scrollController, //Declarate ScrollController
    this.type = StepperType.vertical,
    this.currentStep = 0,
    this.onStepTapped,
    this.onStepContinue,
    this.onStepCancel,
    this.controlsBuilder,
  })  : assert(steps != null),
        assert(type != null),
        assert(currentStep != null),
        assert(0 <= currentStep && currentStep < steps.length),
        super(key: key);
  final ScrollController scrollController;

Once the variable is declared, in the ListView you proceed to add the scrollController as follows:

  Widget _buildVertical() {
    return ListView(
      shrinkWrap: true,
      physics: widget.physics,
      controller: widget.scrollController,//Add ScrollController here
      children: <Widget>[
        for (int i = 0; i < widget.steps.length; i += 1)
          Column(
            key: _keys[i],
            children: <Widget>[
              InkWell(
                onTap: widget.steps[i].state != StepState.disabled
                    ? () {
                        // In the vertical case we need to scroll to the newly tapped
                        // step.
                        Scrollable.ensureVisible(
                          _keys[i].currentContext,
                          curve: Curves.fastOutSlowIn,
                          duration: kThemeAnimationDuration,
                        );

                        if (widget.onStepTapped != null) widget.onStepTapped(i);
                      }
                    : null,
                canRequestFocus: widget.steps[i].state != StepState.disabled,
                child: _buildVerticalHeader(i),
              ),
              _buildVerticalBody(i),
            ],
          ),
      ],
    );
  }

Once that is done, you will have control in the Stepper class, just declare a final variable as scrollController in your document, like this:

final _controller = new ScrollController();

Attach the controller to the Stepper.

When you press onStepContinue, move the animation to the position you want in the controller. I leave you my detailed example below:

import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

class MyStepper extends StatefulWidget {
  @override
  _MyStepperState createState() => _MyStepperState();
}

class _MyStepperState extends State<MyStepper> {
  int _currentStape = 0;
  final _controller = new ScrollController();
  @override
  Widget build(BuildContext context) {
    return Material(
      child: Container(
        width: double.infinity,
        height: double.infinity,
        child: Stepper(
          currentStep: _currentStape,
          scrollController: _controller,
          physics: ClampingScrollPhysics(),
          onStepContinue: () {
            _currentStape++;
            _controller.animateTo(
              0,
              duration: Duration(milliseconds: 100),
              curve: Curves.bounceIn,
            );
            setState(() {});
          },
          onStepTapped: (value) {
            _currentStape = value;
          },
          steps: [
            Step(
              title: FaIcon(
                FontAwesomeIcons.dog,
              ),
              subtitle: Text('Ingresa la información de tu mascota'),
              content: Container(
                height: 500,
              ),
            ),
            Step(
              title: FaIcon(
                FontAwesomeIcons.userAlt,
              ),
              subtitle: Text('Ingresa tú información personal'),
              content: Container(
                height: 500,
              ),
            ),
            Step(
              title: FaIcon(
                FontAwesomeIcons.image,
              ),
              subtitle: Text('Agrega algunas imágenes'),
              content: Text('Contenido'),
            ),
          ],
        ),
      ),
    );
  }
}

I'm use Flutter 1.17.3

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM