4

UI Layout

If the purple area is inside an Expanded widget, how would I go about to position the button? I've implemented that UI by setting a fixed height to the purple container but haven't been able to understand how to achieve the same effect if the height is variable, depending on the content.

I was able to get close by using Stack and Positioned widgets but then the button is not really clickable. If anyone can give me a general idea on how to achieve the desired goal I would be thankful.

Here's my attempt (demo case)

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.start,
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: <Widget>[
        Expanded(
          flex: 1,
          child: SingleChildScrollView(
              child: Column(
                children: <Widget>[
                  Container(
                    decoration: BoxDecoration(
                      color: Colors.redAccent,
                    ),
                    child: Padding(
                      padding: const EdgeInsets.all(20.0),
                      child: Stack(
                          children: <Widget> [
                            Padding(
                              padding: const EdgeInsets.only(bottom: 40.0),
                              child: Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: <Widget>[
                                  Icon(
                                      Icons.book,
                                      color: Colors.white,
                                      size: 40.0
                                  ),
                                  Container(
                                    width: 90.0,
                                    child: new Divider(color: Colors.white),
                                  ),
                                  Text(
                                    "Some random text -",
                                    style: TextStyle(color: Colors.white, fontSize: 25.0),
                                  ),
                                  Padding(
                                    padding: const EdgeInsets.only(top: 8.0, right: 70.0),
                                    child: Row(
                                      children: <Widget>[
                                        Flexible(
                                          child: Text(
                                            'More random text that can vary a lot!',
                                            style: TextStyle(
                                              color: Colors.white,
                                              fontSize: 16.0,
                                              fontWeight: FontWeight.bold,
                                            ),
                                          ),
                                        ),
                                      ],
                                    ),
                                  ),
                                  Padding(
                                    padding: const EdgeInsets.only(top: 8.0),
                                    child: Row(
                                      children: <Widget>[
                                        Text(
                                          'Random text ',
                                          style: TextStyle(
                                            color: Colors.white,
                                            fontSize: 16.0,
                                            fontWeight: FontWeight.bold,
                                          ),
                                        ),
                                      ],
                                    ),
                                  ),
                                  Padding(
                                    padding: const EdgeInsets.only(top: 8.0),
                                    child: Row(
                                      children: <Widget>[
                                        Text(
                                          'Random',
                                          style: TextStyle(
                                            color: Colors.white,
                                            fontSize: 16.0,
                                            fontWeight: FontWeight.bold,
                                          ),
                                        ),
                                      ],
                                    ),
                                  ),
                                ],
                              ),
                            ),
                            Positioned(
                              bottom: 0.0,
                              left: MediaQuery.of(context).size.width - 100.0,
                              child: FractionalTranslation(
                                translation: const Offset(0.0, 0.8),
                                child: FloatingActionButton(
                                  backgroundColor: Colors.white,
                                  foregroundColor: Colors.redAccent,
                                  child: new Icon(
                                      Icons.map
                                  ),
                                  onPressed: () {

                                  },
                                ),
                              ),
                            ),
                          ]
                      ),
                    ),
                  ),
                  Column(
                    mainAxisAlignment: MainAxisAlignment.start,
                    crossAxisAlignment: CrossAxisAlignment.stretch,
                    children: <Widget>[
                      Padding(
                        padding: const EdgeInsets.only(top: 8.0, left: 8.0),
                        child: Row(
                          children: <Widget>[
                            Flexible(
                              child: Text(
                                  "Random text",
                                  style: new TextStyle(
                                      fontFamily: 'Raleway',
                                      fontSize: 16.0,
                                      color: Colors.black38
                                  )
                              ),
                            ),
                          ],
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: Text(
                            "Random text - long text",
                            style: new TextStyle(
                                fontFamily: 'Raleway',
                                fontSize: 18.0
                            )
                        ),
                      ),
                    ],
                  )
                ],
              )
          ),
        ),
      ],
    );

1 Answers1

2

Explaining what I described in the comments:

You can use the FractionalTranslation widget to shift your FAB half way down.

FractionalTranslation(translation: Offset(0, .5), child: FloatingActionButton(...))

This requires you to have it positioned at the bottom of the purple area (referring to your screenshot) beforehand, but I assume that you have that figured out.

creativecreatorormaybenot
  • 114,516
  • 58
  • 291
  • 402
  • It worked but I have a doubt will the hard coded Offset be working perfectly in different types of screen resolutions. – Dhyan V Nov 21 '19 at 07:16
  • 1
    @DhyanV This is a relative offset, i.e. it will always offset it by exactly half, no matter the screen resolution. – creativecreatorormaybenot Nov 21 '19 at 08:21
  • Today I noticed a different issue the bottom part of the button is not responding to clicks (The part that is hanging out of the container) – Dhyan V Nov 22 '19 at 09:56