美文网首页
flutter手写一个非侵入式Drawer

flutter手写一个非侵入式Drawer

作者: 小吉快跑呀 | 来源:发表于2019-07-11 09:41 被阅读0次

总体思路

侧滑控件的实现原理: Flutter中Navigator是用来控制路由栈的,使用方式如下:

Navigator.of(context).push(route);

push接收一个Route,这个Route负责给出具体的widget,普通的Route在显示自己的page时会覆盖掉原本的页面,而PopupRoute就不会,他的效果类似于android中的popupWindow,自带蒙层。

继承PopupRoute,修改参数,重写buildPage,在buildPage中返回一个带侧滑动画的widget

class SlideWindow extends PopupRoute {
  ...
  @override
  Color get barrierColor => null;//去掉蒙层

  @override
  Widget buildPage(BuildContext context, Animation<double> animation,
      Animation<double> secondaryAnimation) {
  ...
    return slideWindowWidget;//page是全屏的
  }

}

布局

这个widget是一个Stack结构,底层是全屏的Container蒙层,上层是一个带侧滑动画的内容widget,暂时只能是SizedBox,因为侧滑动画需要知道widget的宽度,而SizedBox是固定宽度的。

Stack(children: <Widget>[
        //蒙层
      GestureDetector(
        onTap: widget.onTapOutsize,
        child: Container(
          width: MediaQuery.of(context).size.width,
          height: MediaQuery.of(context).size.height,
          color: colorAnimation.value,
        ),
      ),
        //内容层
      Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        alignment: Alignment.centerRight,
        //靠右竖直居中的内容widget
        child: Transform.translate(
          offset: Offset(widgetAnimation.value, 0),
          child: widget.child,
        ),
      )
    ]);

动画

在Flutter中,补间动画Tween的原理和Android中类似,规定value变化范围,value每次变化时setState(),根据最新的value去重建widget,在value变化的过程中,widget时不断重建的,某些属性也在不断被修改,这样就达到了动画效果。

这里需要用到两种动画,一个是内容层的平移,一个是蒙层的颜色变化,代码如下,在初始化状态时设置动画

@override
void initState() {
  super.initState();
    //设置动画控制器
  controller = new AnimationController(
    duration: widget.duration,
    vsync: this,
  );
  //设置插值器
  Animation curve = CurvedAnimation(
      parent: controller, curve: Curves.fastLinearToSlowEaseIn);
  //设置内容层平移动画
  widgetAnimation =
      new Tween(begin: widget.child.width, end: 0.0).animate(curve)
        ..addListener(() {
          setState(() {});
        });
  //设置蒙层颜色动画
  colorAnimation = new ColorTween(
          begin: Colors.black.withOpacity(0),
          end: Colors.black.withOpacity(0.4))
      .animate(curve);
  //开始动画
  controller.forward();
}

然后内容需要用一个Transform变换控件包裹,这个控件可以对child做一些变换,例如移动位置

Transform.translate(
  offset: Offset(widgetAnimation.value, 0),
  child: widget.child,
)

响应退出

调用Navigator.pop()

因为这是一个Route,所以是受Navigator控制的,代码中调用了Navigator.pop()时我们的页面是会消失的,这个消失不做处理的话是不带侧滑动画,也就是很难看,而在pop的过程中,系统会调用Route的didpop方法,所以可以重写这个方法在里面反转动画

@override
bool didPop(result) {
  slideWindowWidget.state.controller.reverse();//反转
  return super.didPop(result);
}
触摸了蒙层

这种情况需要自己去控制,在蒙层上设置GestureDetector,在响应中调用Navigator.pop(),又回到第一种情况

按到了物理返回键

这种情况貌似在ios上不会出现,但是android设备是有返回键的,按了返回键后,系统同样会调用Navigator.pop(),还是回到第一种情况

相关文章

  • flutter手写一个非侵入式Drawer

    总体思路 侧滑控件的实现原理: Flutter中Navigator是用来控制路由栈的,使用方式如下: push接收...

  • APM 探针分析

    概要 APM探针主要有侵入式探针和非侵入式探针。 其中侵入式探针以zipkin为代表,非侵入式探针以pinpoin...

  • Spring 核心 : IOC 处理器扩展

    非侵入式框架 Spring一直标注自己是一个非侵入式框架。非侵入式设计的概念并不新鲜,目标就是降低使用者和框架代码...

  • Spring核心——IOC处理器扩展

    非侵入式框架 Spring一直标注自己是一个非侵入式框架。非侵入式设计的概念并不新鲜,目标就是降低使用者和框架代码...

  • 一个优雅的Swift弹窗组件-JFPopup

    前言 受Flutter bottomSheet,drawer,dialog, 响应式布局的启发。也有基于Swift...

  • 列表(recyclerView、listView及其相关)

    1、RecyclerViewSwipeDismissRecyclerViewSwipeDismiss是一个非侵入式...

  • AOP

    相关依赖 java动态代理 注解aop(侵入式) 非侵入式 XML配置

  • 脑机接口

    最近在研究脑机接口,记录一下 脑机接口分侵入式和非侵入式,身为一个民间玩家,自然是玩玩非侵入式,这也是以后可能给大...

  • 非侵入式和侵入式区别

    非侵入式 允许在应用系统中自由选择和组装Spring框架的各个功能模块,并且不强制要求应用系统的类必须从Sprin...

  • Flutter界面 - 边栏

    Flutter界面 - 边栏 1. Drawer 添加使用一个Drawer左侧边栏部件 2. DrawerH...

网友评论

      本文标题:flutter手写一个非侵入式Drawer

      本文链接:https://www.haomeiwen.com/subject/svtrkctx.html