skip to Main Content

I am building a screen that has data from some math problems, but I’m new to Flutter and for me seems very complicated to place things in fixed places without doing a mess since I don’t know a bunch of widgets that can help me, and I’m pretty sure there’s an easier way to do this screen, so I want to ask if someone can help me with this.

This screen is the result I want

enter image description here

And this is the code I made:

import 'package:flutter/material.dart';

class ProblemsScreen extends StatefulWidget {
  const ProblemsScreen({super.key});

  @override
  State<ProblemsScreen> createState() => _ProblemsScreenState();
}

class _ProblemsScreenState extends State<ProblemsScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          title: const Text('Problem title',
            style: TextStyle(
            color: Colors.white,
            fontSize: 30,
            fontWeight: FontWeight.w300
            ),
          ),
          centerTitle: true,
      ),

      body: Container(
        padding: const EdgeInsets.all(20),
        child:Stack(
          children: <Widget>[
            
            //Timer counter
            const Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text('00:00')
              ],
            ),

            //Timer Icon
            const Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: [
                Icon(Icons.timer)
              ],
            ),

            //Problem data, will be a long string later
            const Center(
              child: Text('Problem data'),
            ),
      
            //Button grid with a label
            Column(
              mainAxisAlignment: MainAxisAlignment.end,
              children: [
                const Text('Select an asnwer'), //Label

                //Button grid
                Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Column(
                      children: [
                        Row(
                          children: [
                            TextButton(onPressed: (){}, child: const Text('Answer 1')), 
                            TextButton(onPressed: (){}, child: const Text('Answer 2')),                               
                          ]
                        ),

                        Row(
                          children: [
                            TextButton(onPressed: (){}, child: const Text('Answer 3')), 
                            TextButton(onPressed: (){}, child: const Text('Answer 4')),                               
                          ]
                        )
                      ],
                    )
                  ],
                )
              ],
            ),
          ],
        ),
      ),
    );
  }
}

As you can see, it is completly a mess beacuse of stack-row-column tricks I did and I find it complex to maintain, can someone show me a different way to do it?

3

Answers


  1. The structure you’re using is actually not that bad, but if you want to look at another approach you might want to look at FlutterFlow

    FlutterFlow Homepage

    This way you won’t have to deal with this kind of code.

    Login or Signup to reply.
  2. You can use widgets or helper methods.
    You don’t have to use Stack as Container widget. Container widget can be column because the layout is going top to bottom.
    And refer to Ivo’s comment, you can use Align instead Row.

    refactored code is like below

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
            colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
            useMaterial3: true,
          ),
          home: const ProblemsScreen(),
        );
      }
    }
    
    class ProblemsScreen extends StatefulWidget {
      const ProblemsScreen({super.key});
    
      @override
      State<ProblemsScreen> createState() => _ProblemsScreenState();
    }
    
    class _ProblemsScreenState extends State<ProblemsScreen> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text(
              'Problem title',
              style: TextStyle(
                  color: Colors.white, fontSize: 30, fontWeight: FontWeight.w300),
            ),
            centerTitle: true,
          ),
          body: Container(
            padding: const EdgeInsets.all(20),
            child: Column(
              children: [
                _buildTimer(),
                const Expanded(
                  child: Center(
                    child: Text('Problem data'),
                  ),
                ),
                _buildAnswers(),
              ],
            ),
          ),
        );
      }
    
      Widget _buildTimer() {
        return const Stack(
          alignment: Alignment.center,
          children: [
            Text('00:00', textAlign: TextAlign.center),
            Align(alignment: Alignment.centerRight, child: Icon(Icons.timer)),
          ],
        );
      }
    
      Widget _buildAnswers() {
        return Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Row(
              mainAxisSize: MainAxisSize.min,
              children: [
              TextButton(onPressed: () {}, child: const Text('Answer 1')),
              TextButton(onPressed: () {}, child: const Text('Answer 2')),
            ],),
            Row(
              mainAxisSize: MainAxisSize.min,
              children: [
              TextButton(onPressed: () {}, child: const Text('Answer 3')),
              TextButton(onPressed: () {}, child: const Text('Answer 4')),
            ],
            ),
          ],
        );
      }
    }
    

    There is a official video for this.

    • widgets
      • it requires more boilerplate code, but Flutter can optimize rendering speed.
      • widget can be constant.
    • helper methods
      • you can write less code.
      • easier to access parent field.
    Login or Signup to reply.
  3. If you want to position your widgets inside a screen you can use Stack and Alignments to poisition your widget. Here is the code for your help

    Container(
          height: double.infinity,
            width: double.infinity,
            padding: const EdgeInsets.all(20),
            child:Stack(
              children: <Widget>[
    
                //Timer counter
                Align(
                  alignment: Alignment.topCenter,
                  child: Text('00:00'),
                ),
                Align(
                  alignment: Alignment.topRight,
                  child: Icon(Icons.timer),
                ),
    
                //Problem data, will be a long string later
                Align(
                  alignment: Alignment.center,
                  child: Text('Problem data'),
                ),
    
                //Button grid with a label
                Align(
                  alignment: Alignment.bottomCenter,
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      const Text('Select an asnwer'), //Label
                      Row(
                        mainAxisSize: MainAxisSize.min,
                          children: [
                            TextButton(onPressed: (){}, child: const Text('Answer 1')),
                            TextButton(onPressed: (){}, child: const Text('Answer 2')),
                          ]
                      ),
                      Row(
                          mainAxisSize: MainAxisSize.min,
                          children: [
                            TextButton(onPressed: (){}, child: const Text('Answer 2')),
                            TextButton(onPressed: (){}, child: const Text('Answer 3')),
                          ]
                      ),
    
                    ],
                  ),
                )
    
              ],
            )
        );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search