flutter手寫一個非侵入式Drawer

總體思路

側(cè)滑控件的實現(xiàn)原理: Flutter中Navigator是用來控制路由棧的傻铣,使用方式如下:

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

push接收一個Route九秀,這個Route負責(zé)給出具體的widget吐葱,普通的Route在顯示自己的page時會覆蓋掉原本的頁面秸仙,而PopupRoute就不會袋坑,他的效果類似于android中的popupWindow咙崎,自帶蒙層优幸。

繼承PopupRoute,修改參數(shù)褪猛,重寫buildPage网杆,在buildPage中返回一個帶側(cè)滑動畫的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結(jié)構(gòu),底層是全屏的Container蒙層伊滋,上層是一個帶側(cè)滑動畫的內(nèi)容widget碳却,暫時只能是SizedBox,因為側(cè)滑動畫需要知道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,
        ),
      ),
        //內(nèi)容層
      Container(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        alignment: Alignment.centerRight,
        //靠右豎直居中的內(nèi)容widget
        child: Transform.translate(
          offset: Offset(widgetAnimation.value, 0),
          child: widget.child,
        ),
      )
    ]);

動畫

在Flutter中,補間動畫Tween的原理和Android中類似筒主,規(guī)定value變化范圍关噪,value每次變化時setState(),根據(jù)最新的value去重建widget乌妙,在value變化的過程中使兔,widget時不斷重建的,某些屬性也在不斷被修改冠胯,這樣就達到了動畫效果火诸。

這里需要用到兩種動畫,一個是內(nèi)容層的平移荠察,一個是蒙層的顏色變化置蜀,代碼如下奈搜,在初始化狀態(tài)時設(shè)置動畫

@override
void initState() {
  super.initState();
    //設(shè)置動畫控制器
  controller = new AnimationController(
    duration: widget.duration,
    vsync: this,
  );
  //設(shè)置插值器
  Animation curve = CurvedAnimation(
      parent: controller, curve: Curves.fastLinearToSlowEaseIn);
  //設(shè)置內(nèi)容層平移動畫
  widgetAnimation =
      new Tween(begin: widget.child.width, end: 0.0).animate(curve)
        ..addListener(() {
          setState(() {});
        });
  //設(shè)置蒙層顏色動畫
  colorAnimation = new ColorTween(
          begin: Colors.black.withOpacity(0),
          end: Colors.black.withOpacity(0.4))
      .animate(curve);
  //開始動畫
  controller.forward();
}

然后內(nèi)容需要用一個Transform變換控件包裹,這個控件可以對child做一些變換盯荤,例如移動位置

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

響應(yīng)退出

調(diào)用Navigator.pop()

因為這是一個Route馋吗,所以是受Navigator控制的,代碼中調(diào)用了Navigator.pop()時我們的頁面是會消失的秋秤,這個消失不做處理的話是不帶側(cè)滑動畫宏粤,也就是很難看,而在pop的過程中灼卢,系統(tǒng)會調(diào)用Route的didpop方法绍哎,所以可以重寫這個方法在里面反轉(zhuǎn)動畫

@override
bool didPop(result) {
  slideWindowWidget.state.controller.reverse();//反轉(zhuǎn)
  return super.didPop(result);
}
觸摸了蒙層

這種情況需要自己去控制,在蒙層上設(shè)置GestureDetector鞋真,在響應(yīng)中調(diào)用Navigator.pop()崇堰,又回到第一種情況

按到了物理返回鍵

這種情況貌似在ios上不會出現(xiàn),但是android設(shè)備是有返回鍵的涩咖,按了返回鍵后海诲,系統(tǒng)同樣會調(diào)用Navigator.pop(),還是回到第一種情況

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末檩互,一起剝皮案震驚了整個濱河市特幔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌闸昨,老刑警劉巖蚯斯,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異零院,居然都是意外死亡溉跃,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門告抄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來撰茎,“玉大人,你說我怎么就攤上這事打洼×浜” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵募疮,是天一觀的道長炫惩。 經(jīng)常有香客問我,道長阿浓,這世上最難降的妖魔是什么他嚷? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上筋蓖,老公的妹妹穿的比我還像新娘卸耘。我一直安慰自己,他們只是感情好粘咖,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布蚣抗。 她就那樣靜靜地躺著,像睡著了一般瓮下。 火紅的嫁衣襯著肌膚如雪翰铡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天讽坏,我揣著相機與錄音锭魔,去河邊找鬼。 笑死路呜,一個胖子當(dāng)著我的面吹牛赂毯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拣宰,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼烦感!你這毒婦竟也來了巡社?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤手趣,失蹤者是張志新(化名)和其女友劉穎晌该,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绿渣,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡朝群,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了中符。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片姜胖。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖淀散,靈堂內(nèi)的尸體忽然破棺而出右莱,到底是詐尸還是另有隱情,我是刑警寧澤档插,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布慢蜓,位于F島的核電站,受9級特大地震影響郭膛,放射性物質(zhì)發(fā)生泄漏晨抡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望耘柱。 院中可真熱鬧如捅,春花似錦、人聲如沸帆谍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽汛蝙。三九已至烈涮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間窖剑,已是汗流浹背坚洽。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留西土,地道東北人讶舰。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像需了,于是被迫代替她去往敵國和親跳昼。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容