Flutter?-?創(chuàng)建一個(gè)底部彈窗

2019/12/5 早9點(diǎn)

Flutter - 創(chuàng)建一個(gè)底部彈窗

1.思路

  • 創(chuàng)建一個(gè)Widget并且定位到屏幕下方:使用Stack + Positioned實(shí)現(xiàn)
  • 這個(gè)Widget具有縱向平移功能:使用SlideTransition實(shí)現(xiàn)
  • 動(dòng)畫的實(shí)現(xiàn):設(shè)置AnimationController以及Tween<Offset>

2.實(shí)現(xiàn)

對(duì)著思路倒著來。

2.1 AnimationController以及Tween<Offset>

新建一個(gè)StatefulWidget并且初始化AnimationController

AnimationController controller;

@override
  void initState() {
    // TODO: implement initState
    super.initState();
    controller = new AnimationController(
        duration: Duration(milliseconds: 200), vsync: this);
  }

因?yàn)槭菑钠聊坏撞繌棾觯詫?duì)應(yīng)的平移描述Tween<Offset>如下:

Tween<Offset> tween;

tween = Tween<Offset>(
  begin: Offset(0.0, 1.0),
  end: Offset(0.0, 0.0),
);

注意,這里的Offset描述規(guī)則是:

  • 起始位置begin - x方向不平移,y方向(由屏幕(0,0)向下為正)處于平移一個(gè)Widget高度的位置
  • 結(jié)束位置end - x方向不平移,y方向不平移原始位置

所以這個(gè)Tween描述的就是從下向上移動(dòng)

所以controller控制彈窗的彈出與收回就是對(duì)動(dòng)畫的順序與逆序播放:

if (widget.show) {
  controller.forward();
} else {
  controller.reverse();
}

2.2 SlideTransition

SlideTransition是一個(gè)動(dòng)畫的封裝類,兩個(gè)參數(shù)分別為:Animation<Offset>Widget:

SlideTransition(
      position: tween.animate(controller),
      child: childWidget,
    )

然后在Widget內(nèi)部設(shè)置一個(gè)flag,用于描述彈窗的彈出與收回,并且將其暴露給外部即可。

2.3 可以滑動(dòng)的Widget

class SlideWidget extends StatefulWidget {
  final bool show;
  final Widget child;

  SlideWidget({
    @required this.show,
    @required this.child,
  });

  @override
  _ChapterAppbarViewState createState() => new _ChapterAppbarViewState();
}

class _SlideWidgetState extends State<SlideWidget>
    with TickerProviderStateMixin {
  AnimationController controller;
  Tween<Offset> tween;

  @override
  void initState() {
    super.initState();
    controller = new AnimationController(
        duration: Duration(milliseconds: 200), vsync: this);
    tween = Tween<Offset>(
      begin: Offset(0.0, 1.0),
      end: Offset(0.0, 0.0),
    );
  }

  @override
  Widget build(BuildContext context) {
    if (widget.show) {
      controller.forward();
    } else {
      controller.reverse();
    }

    Size screenSize = MediaQuery.of(context).size;
    double screenWidth = screenSize.width;
    return SlideTransition(
      position: tween.animate(controller),
      child: widget.child,
    );
  }
}

2.4 Stack + Positioned

最后一步,把這個(gè)Widget放置在屏幕下側(cè)就好:

Stack(
  children: <Widget>[
    ...
    Positioned(
      child: SlideWidget(
          show: needShow,
          child: buildDialog,
      ),
      bottom: 0.0,
      left: 0.0,
    ),
  ],
),

添加點(diǎn)擊事件修改SlideWidgetshow屬性并且刷新就可以實(shí)現(xiàn)平移了。

3. 項(xiàng)目源碼:go實(shí)現(xiàn)的爬蟲服務(wù)器,F(xiàn)lutter進(jìn)行前端展示,如果你覺得不錯(cuò),給我一個(gè)Star吧!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容