【flutter老司机分享①】flutter 无context弹出层

直接上代码,各位自己测试,私人手敲珍藏代码

全部原生,无需任何插件,各位记得复制完点赞😊😊😊😊😊😊😊😊

本github: https://github.com/jeasonlaung/flutter_test2

谢谢各位麻烦点star💕

import 'package:flutter/material.dart';

void main() async{
  runApp(MyApp());
}
class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp>{
  @override
  Widget build(BuildContext context) {
    /// 套接AppContainer
    return AppContainer(
      child: MaterialApp(
        home: HomePage()
      )
    );
  }
}

/// ---------------------------
///
/// 实际应用
///
/// ---------------------------


class HomePage extends StatefulWidget {
  final int index;
  HomePage({this.index = 1});
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('第${widget.index}页'),),
      body: Center(
        child: Column(
          children: [
            RaisedButton(
              child: Text('下一页'),
              onPressed: () {
                Navigator.push(context, MaterialPageRoute(
                  builder: (_) => HomePage(index: widget.index+1,)
                ));
              },
            ),
            RaisedButton(
              child: Text('展示无context toast'),
              onPressed: () {
                showToast('123465');
              },
            ),
            RaisedButton(
              child: Text('展示无context modal'),
              onPressed: () {
                showModal('是否确定',onConfirm: () {
                  showToast('点击了确定');
                },onCancel: () {
                  showToast('点击了取消');

                });
              },
            ),
          ]
        )
      ),
    );
  }
}







/// ----------------------
/// 
/// 核心代码
/// 
/// ----------------------


/// 全局Finderkey
final GlobalKey<_AppContainerFinderState> _keyFinder = GlobalKey(debugLabel: 'overlay_support');
/// 全局overlayState
OverlayState get _overlayState{
  final context = _keyFinder.currentContext;
  if (context == null) return null;
  NavigatorState navigator;
  void visitor(Element element) {
    if (navigator != null) return;
    /// 如果是一个页面路由
    if (element.widget is Navigator) {
      /// navigator返回他的state
      navigator = (element as StatefulElement).state;
    } else {
      /// 否则递归
      element.visitChildElements(visitor);
    }
  }
  /// 就是总能找到最后一页的overlay
  context.visitChildElements(visitor);
  return navigator.overlay;
}

/// 静态app容器
class AppContainer extends StatelessWidget {
  final Widget child;
  AppContainer({this.child});
  @override
  Widget build(BuildContext context) {
    return AppContainerFinder(child: child, key: _keyFinder);
  }
}
/// 动态app容器内容
class AppContainerFinder extends StatefulWidget {
  final Widget child;
  AppContainerFinder({Key key,this.child}) : super(key: key);
  @override
  _AppContainerFinderState createState() => _AppContainerFinderState();
}

class _AppContainerFinderState extends State<AppContainerFinder> {
  @override
  Widget build(BuildContext context) {
    return widget.child;
  }
}













/// ----------------------
/// 
/// 弹出层函数
/// 
/// ----------------------


/// 显示toast 仿微信API
showToast(msg) {
  OverlayEntry overlayEntry = OverlayEntry(builder: (context) {
    //外层使用Positioned进行定位,控制在Overlay中的位置
      return Positioned(
          top: MediaQuery.of(context).size.height * 0.7,
          child: Material(
            child: Container(
              width: MediaQuery.of(context).size.width,
              alignment: Alignment.center,
              child: Center(
                child: Card(
                  child: Padding(
                    padding: EdgeInsets.all(8),
                    child: Text(msg),
                  ),
                  color: Colors.grey,
                ),
              ),
            ),
          ));
    });
    //往Overlay中插入插入OverlayEntry
    _overlayState.insert(overlayEntry);
    //两秒后,移除Toast
    Future.delayed(Duration(seconds: 2)).then((value) {
      overlayEntry.remove();
    });
}

/// showModal 仿微信API
showModal(String msg, {onConfirm, onCancel}) {
    OverlayEntry overlayEntry;
    overlayEntry = OverlayEntry(builder: (context) {
    //外层使用Positioned进行定位,控制在Overlay中的位置
      return Container(
        color: Color(0x66333333),
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Container(
                color: Colors.white,
                height: 100,
                width: MediaQuery.of(context).size.width * 0.8,
                alignment: Alignment.center,
                child: Text('$msg', style: TextStyle(
                  decoration: TextDecoration.none,
                  color: Color(0xff333333),
                  fontWeight: FontWeight.normal,
                  fontSize: 16.0
                ),),
              ),
              SizedBox(
                width: MediaQuery.of(context).size.width * 0.8,
                child: Material(
                child: Row(
                children: <Widget>[
                  Expanded(
                    child: InkWell(
                      child: Container(
                        alignment: Alignment.center,
                        padding: EdgeInsets.all(20),
                        child: Text('取消'),
                      ),
                      onTap: () {
                        overlayEntry.remove();
                        return onCancel != null ? onCancel() : false;
                      },
                    ),
                  ),
                  Expanded(
                    child: InkWell(
                      child: Container(
                        alignment: Alignment.center,
                        padding: EdgeInsets.all(20),
                        child: Text('确定'),
                      ),
                      onTap: () {
                        overlayEntry.remove();
                        return onConfirm != null ? onConfirm() : false;
                      },
                    ),
                  ),
                  
                ],
              ))
              )
            ],
          ),
        ),
      );
    });
    //往Overlay中插入插入OverlayEntry
    _overlayState.insert(overlayEntry);
    //两秒后,移除Toast
    // Future.delayed(Duration(seconds: 2)).then((value) {
    //   overlayEntry.remove();
    // });
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值