Flutter创建背景透明的dialog

2020-01-17  本文已影响0人  Maaaaxi

一般在项目里进行网络请求时都会弹出加载框进行过度,以下是我的项目最开始使用的Loading效果


20200117_115410.gif

因为是继承Dialog所以有灰色背景效果,但是当网络响应特别快的时候,Loading效果刚出现就消失,由于白->灰->白这样快速的过度,就会有一闪而过的效果,导致体验极其不友好,经测试找到了完美的实现方式。

改造前:

class Loading {

  static void show(BuildContext context, {bool mateStyle}) {
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return WillPopScope(
            child: LoadingDialog(),
            onWillPop: () async {
              return Future.value(false);
            });
      },
    );
  }

  static void hide(BuildContext context) {
    Navigator.of(context).pop();
  }
}

class LoadingDialog extends Dialog {

  @override
  Widget build(BuildContext context) {
    return Material(
      //创建透明层
      type: MaterialType.transparency, //透明类型
      child: Center(
        //保证控件居中效果
        child: CupertinoActivityIndicator(
          radius: 18,
        ),
      ),
    );
  }

WillPopScope是禁止loading效果出现时点击手机返回键消失

改造后

class Loading {

  static void show(BuildContext context, {bool mateStyle}) {
    Navigator.of(context)
        .push(DialogRouter(LoadingDialog()));
  }

  static void hide(BuildContext context) {
    Navigator.of(context).pop();
  }
}

class LoadingDialog extends Dialog {

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
        child: Material(
          //创建透明层
          type: MaterialType.transparency, //透明类型
          child: Center(
            //保证控件居中效果
            child: CupertinoActivityIndicator(
              radius: 18,
            ),
          ),
        ),
        onWillPop: () async {
          return Future.value(false);
        });
  }

DialogRouter

import 'package:flutter/material.dart';

class DialogRouter extends PageRouteBuilder{

  final Widget page;

  DialogRouter(this.page)
      : super(
    opaque: false,
    barrierColor: Color(0x00000001),
    pageBuilder: (context, animation, secondaryAnimation) => page,
    transitionsBuilder: (context, animation, secondaryAnimation, child) => child,
  );
}

调用方式

//打开
Loading.show(context);

//关闭
Loading.hide(context);

注意:barrierColor不能使用Colors.transparent,具体原因没有深究

改造后效果

20200117_131513.gif

flutter主张的思想是万物皆widget,所以改造后是使用路由的方式打开dialog,并设置背景色透明。

上一篇 下一篇

猜你喜欢

热点阅读