Creating a Persistent Bottom Button in Flutter

Creating a Persistent Bottom Button in Flutter

This tutorial demonstrates how to implement a button that consistently remains at the bottom of the screen in a Flutter application, regardless of content scrolling. We’ll use the bottomSheet property of the Scaffold widget and enhance the user experience with animations and styling.

Overview

In this demo, we’ll create a screen with the following features:

  1. A scrollable list of paragraphs
  2. A persistent bottom button that stays in place while scrolling
  3. An animation for the button to slide up when the screen loads
  4. Styling to make the button visually appealing

Implementation

import 'package:flutter/material.dart';

class NormalPage extends StatefulWidget {

  const NormalPage({Key? key}) : super(key: key);

  @override

  State<NormalPage> createState() => _NormalPageState();

}

class _NormalPageState extends State<NormalPage> with SingleTickerProviderStateMixin {

  late AnimationController _controller;

  late Animation<double> _animation;

  @override

  void initState() {

    super.initState();

    _controller = AnimationController(

      duration: const Duration(milliseconds: 500),

      vsync: this,

    );

    _animation = CurvedAnimation(

      parent: _controller,

      curve: Curves.easeInOut,

    );

    _controller.forward();

  }

  @override

  void dispose() {

    _controller.dispose();

    super.dispose();

  }

  @override

  Widget build(BuildContext context) {

    return Scaffold(

      appBar: AppBar(

        title: const Text("Sticky Bottom Button Demo"),

        backgroundColor: Colors.teal,

        elevation: 0,

        leading: IconButton(

          icon: const Icon(Icons.menu),

          onPressed: () {},

        ),

        actions: <Widget>[

          IconButton(

            icon: const Icon(Icons.comment),

            onPressed: () {},

          ),

          IconButton(

            icon: const Icon(Icons.settings),

            onPressed: () {},

          ),

        ],

      ),

      body: SingleChildScrollView(

        child: Padding(

          padding: const EdgeInsets.all(16.0),

          child: Column(

            crossAxisAlignment: CrossAxisAlignment.start,

            children: List.generate(

              20,

              (index) => Padding(

                padding: const EdgeInsets.only(bottom: 16.0),

                child: Card(

                  elevation: 2,

                  child: Padding(

                    padding: const EdgeInsets.all(16.0),

                    child: Text(

                      'This is paragraph ${index + 1}',

                      style: Theme.of(context).textTheme.bodyLarge,

                    ),

                  ),

                ),

              ),

            ),

          ),

        ),

      ),

      bottomSheet: SlideTransition(

        position: Tween<Offset>(

          begin: const Offset(0, 1),

          end: Offset.zero,

        ).animate(_animation),

        child: Container(

          width: double.infinity,

          padding: const EdgeInsets.all(16.0),

          decoration: BoxDecoration(

            color: Colors.teal,

            boxShadow: [

              BoxShadow(

                color: Colors.black.withOpacity(0.1),

                blurRadius: 5,

                offset: const Offset(0, -3),

              ),

            ],

          ),

          child: ElevatedButton(

            onPressed: () {

              ScaffoldMessenger.of(context).showSnackBar(

                const SnackBar(content: Text('Button pressed!')),

              );

            },

            style: ElevatedButton.styleFrom(

              primary: Colors.white,

              onPrimary: Colors.teal,

              padding: const EdgeInsets.symmetric(vertical: 16),

              shape: RoundedRectangleBorder(

                borderRadius: BorderRadius.circular(8),

              ),

            ),

            child: const Text('Sticky Bottom Button', style: TextStyle(fontSize: 18)),

          ),

        ),

      ),

    );

  }

}

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注