ezra bell
ezra bell

Reputation: 51

Creating a Sticky Site Footer

I have not been able to locate any documentation for creating footer nav bars with Flutter/Dart. I know that "crossAxisAlignment: CrossAxisAlignment.end" can be used to pull content to the bottom of a column. However, I'm not sure how to render a site footer that sticks to the bottom of the screen. There are various solutions in flex and css grid, but not clear on what implementation would look like in this platform.

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override

  Widget build(BuildContext context) {

    Widget siteLogo = new Container(
      padding: const EdgeInsets.only(top: 100.0),
      child: new Image.asset(
        'images/logo.png',
        width: 180.0,
        height: 180.0,
      ),
    );

    Widget titleTextSection = new Container(
      padding: const EdgeInsets.only(left: 80.0, right: 80.0, top: 30.0, bottom: 20.0),
        child: new Text(
        ''' Welcome to The Site''',
            textAlign: TextAlign.center,
        style: new TextStyle(
          fontSize: 35.0,
          fontWeight: FontWeight.w500,
        ),
      ),
    );

    Widget subtitleTextSection = new Container(
      padding: const EdgeInsets.only(left: 40.0, right: 40.0, bottom: 40.0),
      child: new Text(
        '''Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec imperdiet Donec imperdiet.''',
        textAlign: TextAlign.center,
        style: new TextStyle(
            fontSize: 15.0,
            fontWeight: FontWeight.w400
        ),
      ),
    );


//    footer
    Column signInLink(String label) {

      return new Column(
        mainAxisAlignment: MainAxisAlignment.center,

        children: [
          new Container(
            child: new Text(
              label,
              style: new TextStyle(
                  fontSize: 16.0,
                  fontWeight: FontWeight.w400,
                  color: const Color(0xFFf735e9)
              ),
            ),
          ),
        ],
      );
    }


    Column existingAccountLink(String label) {

      return new Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          new Container(
            child: new Text(
              label,
              style: new TextStyle(
                  fontSize: 16.0,
                  fontWeight: FontWeight.w400,
                  color: const Color(0xFFeceff1)
              ),
            ),
          ),
        ],
      );
    }

    Widget footer = new Container(
      height: 50.0,
      decoration: new BoxDecoration(color: Colors.black),
      child: new Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          existingAccountLink('Already have an account?'),
          signInLink('SIGN IN'),
        ],
      ),
    );

    return new MaterialApp(
      title: 'Flutter Demo',
      home: new Scaffold(
        body: new Container(
          decoration: new BoxDecoration(
            image: new DecorationImage(
              image: new AssetImage('images/backgroundimg.jpg'),
              fit: BoxFit.cover,
            ),
          ),
          child: new ListView(
            children: [
              siteLogo,
              titleTextSection,
              subtitleTextSection,
              footer,
            ],
          ),
        )
      ),
    );
  }
}

As you can see, I am currently using ListView to layout the widgets. The only thing I can think of right now is to put the whole ListView in a single column, crossAxisAlign to End so everything gets pulled down, and then style each widget relative to the footer. There must be a better way though?

Upvotes: 4

Views: 12165

Answers (3)

softmarshmallow
softmarshmallow

Reputation: 1274

you can use Footer from flutter_layouts

sticky footer can be hard to implement. since you have to know the height of footer, it is not possible to perform this in build() function.

try out below flutter package.

https://github.com/softmarshmallow/flutter-layouts/tree/master/lib/src/footer https://github.com/softmarshmallow/flutter-layouts/

by this, you can use footer with scaffold bottom nav. example

import 'package:flutter_layouts/flutter_layouts.dart';
class _FooterScreenState extends State<FooterScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("footer demo"),
      ),
      body: buildBody(),
      bottomNavigationBar: BottomNavigationBar(items: [
        BottomNavigationBarItem(icon: Icon(Icons.add), title: Text("first")),
        BottomNavigationBarItem(icon: Icon(Icons.remove), title: Text("second"))
      ]),
    );
  }

  Widget buildBody() {
    return Footer(
      body: buildContent(),
      footer: buildFooter(),
    );
  }

  Widget buildContent() {
    return ListView.builder(
      itemBuilder: (c, i) {
        return Card(
          margin: EdgeInsets.all(16),
          child: Container(
            padding: EdgeInsets.all(24),
            child: Text("contents"),
          ),
        );
      },
      itemCount: 20,
    );
  }

  Widget buildFooter() {
    return Container(
      padding: EdgeInsets.all(24),
      decoration: BoxDecoration(color: Theme.of(context).primaryColor),
      child: FlatButton(
        onPressed: () {},
        child: Text("Lean more", style: Theme.of(context).textTheme.button.copyWith(
          color: Theme.of(context).colorScheme.onBackground
        ),),
      ),
    );
  }
}

enter image description here

Upvotes: 0

Kennedy Nyagah
Kennedy Nyagah

Reputation: 3645

The use of a listview is an excellent choice when you have a list of items that need a listview. Sometimes the other items in the layout might be fixed and do not need a listview. e.g using a column.

Example on how to achieve fixed bottom footer using stack.

 @override
   Widget build(BuildContext context) {
    return new Material(
      child: Scaffold(
        body: Stack(
        children : <Widget> [
         Text("Top positioned text"),
         Column(
            children : <Widget> [
               Text("Column:Top positioned text"),
               Text("Column:Top positioned text")
             ]
            ),
         Positioned(
            bottom : 0,
            child: Text("Bottom positioned text")
         )
        ]
      )
    }

Upvotes: 2

R&#233;mi Rousselet
R&#233;mi Rousselet

Reputation: 276891

Since you are using Scaffold, you can use bottomNavigationBar to have a 'sticky' bottom widget. (And potentially use BottomNavigationBar if you want to)

new Scaffold(
  appBar: new AppBar(title: new Text("Title")),
  body: new ListView.builder(
    itemBuilder: (context, index) {
      return new ListTile(
        title: new Text("title $index"),
      );
    },
  ),
  bottomNavigationBar: new Container(
    height: 40.0,
    color: Colors.red,
  ),
);

Alternatively your

The only thing I can think of right now is to put the whole ListView in a single column

is not a bad idea at all. That's how things works in flutter. Although MainAxisAlignement.end is not the right way to do it.

You could achieve the same layout as with bottomNavigationBar without a Scaffold, using a Column this way :

new Column(
  children: <Widget>[
    new Expanded(
      child: new ListView.builder(
        itemBuilder: (context, index) {
          return new ListTile(
            title: new Text("title $index"),
          );
        },
      ),
    ),
    new Container(
      height: 40.0,
      color: Colors.red,
    ),
  ],
),

enter image description here

Upvotes: 21

Related Questions