Search code examples
flutterdartflutter-layoutstepper

Flutter 3: Row layout not showing up in a Stepper


I am working on an onboarding screen where I want to have the onboarding in 3 steps, so using the Stepper widget. The Stepper widget is inside a Column as I want to have some text displayed over the Stepper first. But now when I am trying to use a Row inside the Step widget to display some data horizontally, it does not show up. But it works if I make it a Column. What could be causing this and any possible fix?

Flutter version: 3.3.8

What I am trying:

Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 12.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              const SizedBox(height: 40),
              const Text('Hi there!', style: AppStyles.heading),
              const Text(
                'Let\'s get you started',
                style: AppStyles.subheading,
              ),
              const SizedBox(
                height: 50,
              ),
              Stepper(
                type: StepperType.vertical,
                currentStep: _currentStep,
                physics: const ScrollPhysics(),
                onStepTapped: (step) => onTapped(step),
                onStepContinue: onContinued,
                onStepCancel: onCancel,
                steps: [
                  Step(
                    title: const Text('Select a book'),
                    content: CustomButton(onPressed: () {}, text: 'Find Book'),
                  ),
                  Step(
                      title: const Text('Set your goal'),
                      content: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          const TextField(
                            decoration: InputDecoration(
                              hintText: 'Pages',
                            ),
                            keyboardType: TextInputType.number,
                          ),
                          const SizedBox(width: 10),
                          CustomButton(onPressed: () {}, text: 'Set Goal'),
                        ],
                      )),
                  const Step(
                      title: Text('When you want to be reminded'),
                      content: TimePickerDialog(
                        initialTime: TimeOfDay(hour: 8, minute: 0),
                      ))
                ],
                controlsBuilder: (context, _) {
                  return Row(
                    children: <Widget>[
                      TextButton(
                        onPressed: () => onContinued(),
                        child: const Text('Next'),
                      ),
                      TextButton(
                        onPressed: () => onCancel(),
                        child: const Text('Back'),
                      ),
                    ],
                  );
                },
              )
            ],
          ),
        ),
      ),
    );
  }

CustomButton widget:

class CustomButton extends StatelessWidget {
  final String text;
  final bool isOutlined;
  final bool isLoading;
  final bool isDisabled;
  final VoidCallback onPressed;

  const CustomButton(
      {Key? key,
      required this.text,
      this.isOutlined = false,
      this.isLoading = false,
      this.isDisabled = false,
      required this.onPressed})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: onPressed,
      style: ElevatedButton.styleFrom(
          minimumSize: const Size.fromHeight(50),
          backgroundColor: isOutlined ? Colors.white : Pallete.primaryBlue,
          padding: const EdgeInsets.symmetric(horizontal: 50, vertical: 18),
          foregroundColor: isOutlined ? Pallete.primaryBlue : null,
          elevation: 4,
          side: isOutlined
              ? const BorderSide(color: Pallete.primaryBlue, width: 1.0)
              : null,
          shape:
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(10))),
      child: Stack(
        children: [
          Visibility(
            visible: isLoading ? false : true,
            child: Text(text,
                style: const TextStyle(
                    fontSize: 18.0, fontWeight: FontWeight.w600)),
          ),
          Visibility(
              visible: isLoading,
              child: Loader(
                color: isOutlined ? Pallete.primaryBlue : Pallete.white,
              ))
        ],
      ),
    );
  }
}

Output

image


Solution

  • Wrap your TextField and CustomButton (while it has ElevatedButton) with Expanded widget.

    Step(
        title: const Text('Set your goal'),
        content: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Expanded(
              child: const TextField(
                decoration: InputDecoration(
                  hintText: 'Pages',
                ),
                keyboardType: TextInputType.number,
              ),
            ),
            const SizedBox(width: 10),
            Expanded(
                child: CustomButton(
                    onPressed: () {}, text: 'Set Goal')),
          ],
        )),
    

    Find more about constraints