从屏幕顶部抖动通知

时间:2018-11-09 03:49:11

标签: flutter

我试图弄清楚如何像正常的推送通知一样,用来自屏幕顶部的警报通知用户。 如何从屏幕顶部提醒用户。
AlertDialog不可自定义,因此我坚持使用此方法。有什么方法可以从屏幕顶部显示警报或小吃店之类的东西吗?

2 个答案:

答案 0 :(得分:4)

Flutter使您可以借助类Overlay创建通知。要使这些动画从顶部进入屏幕,您可以将SlideTransitionAnimationController结合使用。这是我创建的示例应用程序:

enter image description here

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: Home());
  }
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: RaisedButton.icon(
          icon: Icon(Icons.notifications_active),
          label: Text('Notify!'),
          onPressed: () {
            Navigator.of(context)
                .overlay
                .insert(OverlayEntry(builder: (BuildContext context) {
              return FunkyNotification();
            }));
          },
        ),
      ),
    );
  }
}

class FunkyNotification extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => FunkyNotificationState();
}

class FunkyNotificationState extends State<FunkyNotification>
    with SingleTickerProviderStateMixin {
  AnimationController controller;
  Animation<Offset> position;

  @override
  void initState() {
    super.initState();

    controller =
        AnimationController(vsync: this, duration: Duration(milliseconds: 750));
    position = Tween<Offset>(begin: Offset(0.0, -4.0), end: Offset.zero)
        .animate(
            CurvedAnimation(parent: controller, curve: Curves.bounceInOut));

    controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Material(
        color: Colors.transparent,
        child: Align(
          alignment: Alignment.topCenter,
          child: Padding(
            padding: EdgeInsets.only(top: 32.0),
            child: SlideTransition(
              position: position,
              child: Container(
                decoration: ShapeDecoration(
                    color: Colors.deepPurple,
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(16.0))),
                child: Padding(
                  padding: EdgeInsets.all(10.0),
                  child: Text(
                    'Notification!',
                    style: TextStyle(
                        color: Colors.white, fontWeight: FontWeight.bold),
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

答案 1 :(得分:0)

在这里您可以使用向上或向下滑动来关闭通知。这是应用内促销的完美通知。

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> with TickerProviderStateMixin {
  bool _fromTop = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.fireplace_outlined),
        onPressed: () {
          showGeneralDialog(
            barrierLabel: "Label",
            barrierDismissible: true,
            barrierColor: Colors.transparent,
            transitionDuration: Duration(milliseconds: 700),
            context: context,
            pageBuilder: (context, anim1, anim2) {
              return GestureDetector(
                onVerticalDragUpdate: (dragUpdateDetails) {
                  Navigator.of(context).pop();
                },
                child: Column(
                  children: [
                    SizedBox(height: 40),
                    Card(
                      margin:
                          EdgeInsets.symmetric(vertical: 20, horizontal: 10),
                      child: Container(
                        height: 100,
                        child: Image.asset('lib/model/promo.png',
                            fit: BoxFit.fill),
                        decoration: BoxDecoration(
                          color: Colors.white,
                          borderRadius: BorderRadius.circular(40),
                        ),
                      ),
                    ),
                  ],
                ),
              );
            },
            transitionBuilder: (context, anim1, anim2, child) {
              return SlideTransition(
                position: anim1.drive(Tween(
                        begin: Offset(0, _fromTop ? -1 : 1), end: Offset(0, 0))
                    .chain(CurveTween(curve: Sprung()))),
                child: child,
              );
            },
          );
        },
      ),
    );
  }
}

class Sprung extends Curve {
  factory Sprung([double damping = 20]) => Sprung.custom(damping: damping);

  Sprung.custom({
    double damping = 20,
    double stiffness = 180,
    double mass = 1.0,
    double velocity = 0.0,
  }) : this._sim = SpringSimulation(
          SpringDescription(
            damping: damping,
            mass: mass,
            stiffness: stiffness,
          ),
          0.0,
          1.0,
          velocity,
        );

  final SpringSimulation _sim;

  @override
  double transform(double t) => _sim.x(t) + t * (1 - _sim.x(1.0));
}