Git Product home page Git Product logo

sliver_fab's Introduction

sliver_fab

A wrapper widget allowing to place a widget on the edge of FlexibleSpacebar.

gif

gif

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Builder(
        builder: (context) =>
        new SliverFab(
          floatingWidget: FloatingActionButton(
            onPressed: () =>
                Scaffold.of(context).showSnackBar(
                    SnackBar(content: Text("You clicked FAB!"))),
            child: Icon(Icons.add),
          ),
          floatingPosition: FloatingPosition(right: 16),
          expandedHeight: 256.0,
          slivers: <Widget>[
            new SliverAppBar(
              expandedHeight: 256.0,
              pinned: true,
              flexibleSpace: new FlexibleSpaceBar(
                title: new Text("SliverFab Example"),
                background: new Image.asset(
                  "img.jpg",
                  fit: BoxFit.cover,
                ),
              ),
            ),
            new SliverList(
              delegate: new SliverChildListDelegate(
                new List.generate(
                  30,
                      (int index) =>
                  new ListTile(title: new Text("Item $index")),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Installing

1. Depend on it

Add this to your package's pubspec.yaml file:

dependencies:
  sliver_fab: "^1.0.0"

2. Install it

You can install packages from the command line:

with Flutter:

$ flutter packages get

Alternatively, your editor might support packages get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:

import 'package:sliver_fab/sliver_fab.dart';

Contributing

This package was made mostly for use case I needed. If you fill it is missing any features or you have found a bug, pull requests are very welcome!

sliver_fab's People

Contributors

allandaleho avatar marcinusx avatar matheusperez avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sliver_fab's Issues

ScrollController should be a parameter

There will be use cases that users might want to have control over the scrolling within the CustomScrollView. It would be really helpful to add it as a parameter.

I'll be happy to add a PR.

Upgrade to Dart 2

First things first: great plugin. Thanks for that. Could you please update to Dart 2, so we can keep using it in our App? I would do it myself and send you a PR, but I don't have the resources to make myself familiar with your plugin ATM. Maybe you just have to change your pubspec.yaml. Would really appreciate the update.

Phone notches cutting FABs

If you try working with this widget in a phone with a display cut-out, such as an iPhone X, it actually cuts the FAB or any kind of widget you're using as the floatingWidget parameter.

Need a change for stretchmode zoom

Hey i had made changes to code to support stretchmode zoom for floating button.

I have introduced a variable named isStretchModeZoom which handles the offset for floating button accordingly

library sliver_fab;

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

/// A helper class if you want a FloatingActionButton to be pinned in the FlexibleAppBar
class SliverFAB extends StatefulWidget {
  ///List of slivers placed in CustomScrollView
  final List<Widget> slivers;

  ///FloatingActionButton placed on the edge of FlexibleAppBar and rest of view
  final Widget floatingWidget;

  ///Expanded height of FlexibleAppBar
  final double expandedHeight;

  ///Number of pixels from top from which the [floatingWidget] should start shrinking.
  ///E.g. If your SliverAppBar is pinned, I would recommend this leaving as default 96.0
  ///     If you want [floatingActionButton] to shrink earlier, increase the value.
  final double topScalingEdge;

  ///Position of the widget.
  final FloatingPosition floatingPosition;

  ///Handle zoom offset.
  final bool isStretchModeZoom;

  SliverFAB({
    @required this.slivers,
    @required this.floatingWidget,
    this.floatingPosition = const FloatingPosition(right: 16.0),
    this.expandedHeight = 256.0,
    this.topScalingEdge = 96.0,
    this.isStretchModeZoom = false,
  }) {
    assert(slivers != null);
    assert(floatingWidget != null);
    assert(floatingPosition != null);
    assert(expandedHeight != null);
    assert(topScalingEdge != null);
  }

  @override
  State<StatefulWidget> createState() {
    return SliverFABState();
  }
}

class SliverFABState extends State<SliverFAB> {
  ScrollController scrollController;

  @override
  void initState() {
    super.initState();
    scrollController = ScrollController();
    scrollController.addListener(() => setState(() {}));
  }

  @override
  void dispose() {
    scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        CustomScrollView(
          controller: scrollController,
          slivers: widget.slivers,
        ),
        _buildFab(),
      ],
    );
  }

  Widget _buildFab() {
    final double defaultFabSize = 56.0;
    final double paddingTop = MediaQuery.of(context).padding.top;
    final double defaultTopMargin = widget.expandedHeight +
        paddingTop +
        (widget.floatingPosition.top ?? 0) -
        defaultFabSize / 2;

    final double scale0edge = widget.expandedHeight - kToolbarHeight;
    final double scale1edge = defaultTopMargin - widget.topScalingEdge;

    double top = defaultTopMargin;
    double scale = 1.0;
    if (scrollController.hasClients) {
      double offset = scrollController.offset;

      if (!widget.isStretchModeZoom) {
        top -= offset > 0 ? offset : 0;
      } else {
        top -= offset > 0 ? offset : offset;
      }
      if (offset < scale1edge) {
        scale = 1.0;
      } else if (offset > scale0edge) {
        scale = 0.0;
      } else {
        scale = (scale0edge - offset) / (scale0edge - scale1edge);
      }
    }

    return Positioned(
      top: top,
      right: widget.floatingPosition.right,
      left: widget.floatingPosition.left,
      child: Transform(
        transform: Matrix4.identity()..scale(scale, scale),
        alignment: Alignment.center,
        child: widget.floatingWidget,
      ),
    );
  }
}

///A class representing position of the widget.
///At least one value should be not null
class FloatingPosition {
  ///Can be negative. Represents how much should you change the default position.
  ///E.g. if your widget is bigger than normal [FloatingActionButton] by 20 pixels,
  ///you can set it to -10 to make it stick to the edge
  final double top;

  ///Margin from the right. Should be positive.
  ///The widget will stretch if both [right] and [left] are not nulls.
  final double right;

  ///Margin from the left. Should be positive.
  ///The widget will stretch if both [right] and [left] are not nulls.
  final double left;

  const FloatingPosition({this.top, this.right, this.left});
}

How can we use it under DefaultTabController?

I have a SliverAppBar implementation with tab bar views and I tried to use the SliverFab inside the DefaultTabController and it's not working.

Any idea, how can we use it along with DefaultTabController?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.