flutter入门之使用PopupRoute自定义实现PopupWindow功能

    【原创不易,转载请注明出处:https://blog.csdn.net/email_jade/article/details/87922051

    本文起因是由于一个弹窗,要实现一个能够通过点击显示隐藏的功能,效果如下:

    第一选择是采用原生的PopupMenuItem,但是本应用的需求比较特殊,弹出的item自带背景图片,并且图片上面附件了一个Text的文本,item个数恒定为1个。采用PopupMenuItem会给弹出的item附加一个背景色,默认是跟Theme的cardColor颜色,导致图片周围有颜色,并且点击的时候也会有颜色,看起来体验极差,放弃该方案。

   第二选择是采用一个隐藏的widget,当点击的时候展示,然后点击其他地方的时候隐藏,这个方案是可行的,但是由于该页面有很多点击事件,如果每个事件做处理比较麻烦。

    第三种方案是模拟原生的PopupMenuItem的控件,自定义子控件。于是阅读源代码,发现了PopupRoute,这是一个可以弹出透明的布局的抽象Route,因此需要自定义一个PopRoute,代码如下:

class PopRoute extends PopupRoute{
  final Duration _duration = Duration(milliseconds: 300);
  Widget child;

  PopRoute({@required this.child});

  @override
  Color get barrierColor => null;

  @override
  bool get barrierDismissible => true;

  @override
  String get barrierLabel => null;

  @override
  Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
    return child;
  }

  @override
  Duration get transitionDuration => _duration;

}

    需要注意的是transitionDuration不能返回null,否则会报错。

    这个Route是为了点击按钮的时候弹出一个新的页面,这个新页面除了自己定义的child,其他全是透明,来看看新的页面的代码:

class Popup extends StatelessWidget{
  final Widget child;
  final Function onClick; //点击child事件
  final double left; //距离左边位置
  final double top; //距离上面位置

  Popup({
    @required this.child,
    this.onClick,
    this.left,
    this.top,
  });

  @override
  Widget build(BuildContext context) {
    return Material(color: Colors.transparent, child: GestureDetector(child: Stack(
      children: <Widget>[
        Container(width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, color: Colors.transparent,),
        Positioned(child: GestureDetector(child: child, onTap: (){ //点击子child
          if(onClick != null){ 
            Navigator.of(context).pop();
            onClick();
          }
        }),
        left: left,
        top: top,),
      ],
    ),
      onTap: (){ //点击空白处
        Navigator.of(context).pop();
      },
    ),);
  }

}

    以上代码就是用来展示的popup的代码了。

    来看看是怎么使用的:

  ///构建用户头像按钮
  ///点击头像弹出退出按钮
  Widget _buildUserIcon() {
    return Padding(
      padding: EdgeInsets.fromLTRB(20, 22, 0, 0),
      child: GestureDetector(
        child: Container(
            child: Image.asset(
              "assets/images/icon_user.png",
            ),
            width: 32,
            height: 32,
            alignment: AlignmentDirectional.bottomStart),
        onTap: _showExit,
      ),
    );
  }

  ///构建退出按钮
  Widget _buildExit() {
    return Container(
      width: 91,
      height: 36,
      child: Stack(
        children: <Widget>[
          Image.asset(
            "assets/images/exit.png",
            fit: BoxFit.fill,
          ),
          Center(
            child: Text(
              ProjectLocalizations.of(context).exit,
              style: TextStyle(fontSize: 14, color: Colors.black),
            ),
          ),
        ],
      ),
    );
  }

  ///弹出退出按钮
  ///点击退出调用onClick
  void _showExit() {
    Navigator.push(context, PopRoute(child: Popup(
        child: _buildExit(),
    left: 64,
    top: 22,
    onClick: (){
    print("exit");
    },
    ),),);
  }

    使用起来也很方便,直接用Navigator的push方法即可,需要注意的是可以通过left和top计算出来新页面item的展示位置,可以通过onClick监听item的点击事件。

    以上就是自定义PopupWindow的全部内容了,代码比较少,并且全部贴在博客中了,就不贴GitHub地址了。

 

    flutter很好,路还很长,让我们一起奋斗前行!

 

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
可以使用Flutter的camera插件来实现在Android Studio中调用手机模拟器摄像头实现拍照功能。以下是实现步骤: 1. 在pubspec.yaml文件中添加camera插件依赖: ``` dependencies: camera: ^0.9.4+5 ``` 2. 在Flutter项目中引入camera插件: ``` import 'package:camera/camera.dart'; ``` 3. 初始化摄像头: ``` List<CameraDescription> cameras; Future<void> initCamera() async { cameras = await availableCameras(); // 选择第一个摄像头 final firstCamera = cameras.first; final camera = CameraController( firstCamera, ResolutionPreset.medium, ); await camera.initialize(); setState(() { _camera = camera; }); } ``` 4. 在Flutter页面中显示摄像头预览: ``` @override void initState() { super.initState(); initCamera(); } @override void dispose() { _camera.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: _camera == null ? Container() : AspectRatio( aspectRatio: _camera.value.aspectRatio, child: CameraPreview(_camera), ), ); } ``` 5. 实现拍照功能: ``` void takePicture() async { final picturePath = join( (await getTemporaryDirectory()).path, '${DateTime.now()}.png', ); await _camera.takePicture(picturePath); } ``` 6. 在Flutter页面中添加一个按钮,调用takePicture()方法实现拍照: ``` FloatingActionButton( onPressed: takePicture, child: Icon(Icons.camera_alt), ), ``` 完成上述步骤后,您就可以在Android Studio中调用手机模拟器摄像头实现拍照功能了。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值