Flutter自己实现一个ProgressHUD
用惯了iOS的SVProgressHUD,但是在flutter pub上的并没有找到类似的实现,于是自己实现一个
主要实现四个基本功能
- Loading显示
- 成功显示
- 错误显示
- 进度显示:环形进度条和文字
库地址
dependencies:
bmprogresshud: ^0.0.2
复制代码
实现效果
- 由于HUD是盖在视图上面的,通常是整个页面,故考虑直接在目标Widget上套一层
ProgressHUD
- 我们需要在特定的地方获取
ProgressHUD
进行操作,这个有点类似Navigator
,参考Navigator的用法,通过of
方法获得
实际效果如下
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("hud demo"),
),
body: ProgressHud(
child: Container(
child: Builder(builder: (context) {
return RaisedButton(
onPressed: () async {
ProgressHud.of(context).show(ProgressHudType.loading, "加载中...");
await Future.delayed(const Duration(seconds: 1));
ProgressHud.of(context).dismiss();
},
child: Text("加载数据"),
);
}),
),
)
);
}
复制代码
实现效果
1. 显示和隐藏渐变
通过属性opacity
和AnimationController
控制透明度,当透明度为0时候,通过Offstage
控制控件的隐藏
class ProgressHudState extends State<ProgressHud> with SingleTickerProviderStateMixin {
AnimationController _animation;
var _opacity = 0.0;
var _isVisible = false;
@override
void initState() {
_animation = AnimationController(
duration: const Duration(milliseconds: 200),
vsync: this
)..addListener(() {
setState(() {
// 修改透明度
_opacity = _animation.value;
});
})..addStatusListener((status) {
if (status == AnimationStatus.dismissed) {
setState(() {
// 隐藏动画结束,隐藏控件
_isVisible = false;
});
}
});
super.initState();
}
...
}
复制代码
我们通过动画的执行方向控制动画
// 显示动画
_animation.forward();
setState(() {
_isVisible = true;
});
// 隐藏动画
_animation.reverse();
复制代码
2. 通过BuildContext
获得Element树的ProgressHUD
class ProgressHud extends StatefulWidget {
static ProgressHudState of(BuildContext context) {
return context.ancestorStateOfType(const TypeMatcher<ProgressHudState>());
}
...
}
复制代码
3. 创建HUD
Widget _createHudView(Widget child) {
return Stack(
children: <Widget>[
// 如果不想屏蔽用户操作,ignoring设置为true,这里设置为无法响应
IgnorePointer(
ignoring: false,
child: Container(
color: Colors.transparent,
width: double.infinity,
height: double.infinity,
),
),
Center(
child: Container(
// 这里设置一定的偏移,因为iPhoneX有下方安全区域,看起来会偏下
margin: EdgeInsets.fromLTRB(10, 10, 10, 10 - widget.offsetY * 2),
decoration: BoxDecoration(
color: Color.fromARGB(255, 33, 33, 33),
borderRadius: BorderRadius.circular(5)
),
// 设置最小宽高,如果文字比较多,可以自适应
constraints: BoxConstraints(
minHeight: 130,
minWidth: 130
),
child: Padding(
padding: EdgeInsets.all(12),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
padding: EdgeInsets.all(15),
child: child,
),
Container(
child: Text(
_text,
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white, fontSize: 16)
),
)
],
),
),
),
),
],
);
}
复制代码
4. 环形进度
通过Painter画两个圆
import 'dart:math';
import 'package:flutter/material.dart';
class CircleProgressBarPainter extends CustomPainter {
final double progress;
final double strokeWidth;
final Color color;
final Color fillColor;
const CircleProgressBarPainter({
this.progress = 0,
this.strokeWidth = 3,
this.color = Colors.grey,
this.fillColor = Colors.white
});
@override
void paint(Canvas canvas, Size size) {
final paint = new Paint()
..color = this.color
..style = PaintingStyle.stroke
..strokeWidth = strokeWidth;
final double diam = min(size.width, size.height);
final centerX = size.width * 0.5;
final centerY = size.height * 0.5;
final radius = diam / 2.0;
canvas.drawCircle(Offset(centerX, centerY), radius, paint);
paint.color = this.fillColor;
// draw in center
var rect = Rect.fromLTWH((size.width - diam) * 0.5, 0, diam, diam);
canvas.drawArc(rect, -0.5 * pi, progress * 2 * pi, false, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}
复制代码
完整代码见这里:
Flutter自己实现一个ProgressHUD的更多相关文章
- [Flutter] 写第一个 Flutter app,part1 要点
模拟器中调试元素的布局: Android Studio 右侧边栏 Flutter Inspector,选择 Toggle Debug Paint 打开. 格式化代码: 编辑器中右键 Reformat ...
- 【Flutter】Demo1一个名字生成器
根据官网的例子敲的~效果还是很棒的! 首先导入一个第三方包,可以用来随机生成单词组合 在 pubsepec.yaml下添加如下语句 dependencies: flutter: sdk: flutte ...
- 第二篇-用Flutter手撸一个抖音国内版,看看有多炫
前言 继上一篇使用Flutter开发的抖音国际版 后再次撸一个国内版抖音,大部分功能已完成,主要是Flutter开发APP速度很爽, 先看下图 项目主要结构介绍 这次主要的改动在api.dart 及 ...
- 第四篇-用Flutter手撸一个抖音国内版,看看有多炫
前言 这次对布局进行优化,主要包含了首页tabview pageview 以及添加几个按钮的操作过程.主要使用到stack层叠布局,tabpview和pageview,tabview两个页面,一个关注 ...
- 第五篇- 抖音的强大对手来了,用Flutter手撸一个抖音国际版,看看有多炫
前言 由于中间几个月项目天天加班,导致没没时间更新,最近一段时间对前端进行了重构,加了很多页面,如登录.注册.关注.个人中心等,目前写这个纯属业余个人爱好,所以断断续续的继续在做...... 前端地址 ...
- iOS开发之自己封装一个progressHUD控件
看了几个轻量级的progress view 我觉得KVNProgress做的最漂亮吧 突然我想为什么我自己不封装一个控件 然后我研究了一下KVNProgress KVN简单的界面是由storyboar ...
- Flutter新手第一个坑:Could not find com.android.tools.lint:lint-gradle:26.1.1.
解决方法1:修改build.gradle,注释掉jcenter(),google().使用阿里的镜像.原因是jcenter google库无法访问到导致的问题.虽然我有万能的爬墙工具,开启全局代理依然 ...
- 第三篇-用Flutter手撸一个抖音国内版,看看有多炫
前言 前一篇已经开发了大部分框架,包含视频上下滑动播放,这次将上次未完成的数据显示友好显示,以及底部音乐走马灯特效,另外优化了加载数据的bug,在dart语言里 & 会自动变成& 另 ...
- 创建你的第一个Flutter应用程序
前言 Flutter,Google推出的跨平台开发框架.就在前几天,Flutter的首个发布预览版(Release Preview 1)正式发布! 即将迎来Flutter 正式版(1.0).本篇将带你 ...
随机推荐
- dict字典的用法
在用dict遇到了一些困难,记一下. 代码1: books={"倚天屠龙记":{"id":1,"price":100}, "好吗好 ...
- 【linux】【tomcat】linux下定时重启tomcat 【CentOS 6.4】【CentOS 7.6】
本章内容以CentOS 6.4 和 CentOS 7.6 两个版本为例.[6和7的命令不同] 转载 :https://www.cnblogs.com/sxdcgaq8080/p/10730 ...
- jdk1.8 新特性之Stream
--------------------- 作者:码农农码一生 来源:CSDN 原文:https://blog.csdn.net/chenhao_c_h/article/details/8069128 ...
- CAS单点登录系列之极速入门于实战教程(4.2.7)
@ 目录 一. SSO简介 1.1 单点登录定义 1.2 单点登录角色 1.3 单点登录分类 二. CAS简介 2.1 CAS简单定义 2.2 CAS体系结构 2.3 CAS原理 三.CAS服务端搭建 ...
- Linux 文件管理篇(三 属性管理)
可读 r 可写 w 可执行 x 档案属性: 第一栏:执行list -al后第一栏的十个标志[1 - 10] 1: d 目录 - 档案 l 连 ...
- mysql导出
--all-databases , -A 导出全部数据库. mysqldump -uroot -p --all-databases --all-tablespaces , -Y 导出全部表空间. my ...
- C语言实现顺序栈以及栈的特点
什么是栈? 同顺序表和链表一样,栈也是用来存储逻辑关系为 "一对一" 数据的线性存储结构,如下图所示. 从上图我们看到,栈存储结构与之前所学的线性存储结构有所差异,这缘于栈对数据 ...
- spark本地开发环境搭建及打包配置
在idea中新建工程 删除新项目的src,创建moudle 在父pom中添加spark和scala依赖,我们项目中用scala开发模型,建议scala,开发体验会更好(java.python也可以) ...
- leetcode c++做题思路和题解(5)——堆的例题和总结
堆和优先队列 堆的简介, 是一种二叉树, 有最大堆和最小堆miniheap. 通常用于构建优先队列. 0. 目录 数据流中的第K大元素 1. 数据流中的第K大元素 数据流中的第K大元素 复杂度为log ...
- synchronized 的真正含义
@synchronized 锁的永远是对象 ,只针对于对象,只能锁对象,常量等是不能加synchronized,一旦加编译也不会通过 @synchronized 锁对象中的非static 就是锁调用该 ...