利用Flutter制作一个摸鱼桌面版App

目录
  • 准备工作
  • 开始敲代码
    • 找到资源
    • 思考布局
    • 实现布局
    • 思考动画
    • 实现动画
  • 结语

Win10商店上架了一款名为《摸鱼》的App,在下载打开之后,这个App会让你的电脑进入一个假更新的画面,让别人以为你的电脑正在升级,这时候你就可以休息一下,优雅地喝一杯咖啡。 

顿时这个念头划过了我的脑海:好东西,但是我用的是 MacBook,不能用这个应用。但是貌似我可以自己写一个?

准备工作

年轻最需要的就是行动力,想到就干,尽管我此刻正在理顺 DevFest 的讲稿,但丝毫不妨碍我用 10 分钟写一个 App。于是我打出了一套组合拳:

flutter config --enable-macos-desktop
flutter create --platforms=macos touch_fish_on_macos

一个支持 macOS 的 Flutter 项目就创建好了。(此时大约过去了 1 分钟)

开始敲代码

找到资源

我们首先需要一张高清无码的 图片,这里你可以在网上进行搜寻,有一点需要注意的是,使用 LOGO 要注意使用场景带来的版权问题。找到图片后,丢到 assets/apple-logo.png,并在 pubspec.yaml 中加上资源引用:

flutter:
  use-material-design: true
+ assets:
+   - assets/apple-logo.png

思考布局

我们来观察一下 macOS 的启动画面,有几个要点:

LOGO 在屏幕中间,固定大小约为 100dp;

LOGO 与进度条间隔约 100 dp;

进度条高度约 5dp,宽度约 200dp,圆角几乎完全覆盖高度,值部分为白色,背景部分为填充色+浅灰色边框。

(别问我为什么这些东西能观察出来,问就是天天教 UI 改 UI。)

确认了大概的布局模式,接下来我们开始搭布局。(此时大约过去了 2 分钟)

实现布局

首先将 LOGO 居中、着色、设定宽度为 100,上下间隔 100:

return Center(
  child: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: <Widget>[
      const Spacer(),
      Padding(
        padding: const EdgeInsets.symmetric(vertical: 100),
        child: Image.asset(
          'assets/apple-logo.png',
          color: CupertinoColors.white, // 使用 Cupertino 系列的白色着色
          width: 100,
        ),
      ),
      const Spacer(),
    ],
  ),
);

然后在下方放一个相对靠上的进度条:

return Center(
  child: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: <Widget>[
      const Spacer(),
      Padding(
        padding: const EdgeInsets.symmetric(vertical: 100),
        child: Image.asset(
          'assets/apple-logo.png',
          color: CupertinoColors.white, // 使用 Cupertino 系列的白色
          width: 100,
        ),
      ),
      Expanded(
        child: Container(
          width: 200,
          alignment: Alignment.topCenter, // 相对靠上中部对齐
          child: DecoratedBox(
            border: Border.all(color: CupertinoColors.systemGrey), // 设置边框
            borderRadius: BorderRadius.circular(10), // 这里的值比高大就行
          ),
          child: ClipRRect(
            borderRadius: BorderRadius.circular(10), // 需要进行圆角裁剪
            child: LinearProgressIndicator(
              value: 0.3, // 当前的进度值
              backgroundColor: CupertinoColors.lightBackgroundGray.withOpacity(.3),
              color: CupertinoColors.white,
              minHeight: 5, // 设置进度条的高度
            ),
          ),
        ),
      ),
    ],
  ),
);

到这里你可以直接 run,一个静态的界面已经做好了。(此时大约过去了 4 分钟)

打开 App,你已经可以放在一旁挂机了,老板走到你的身边,可能会跟你闲聊更新的内容。但是,更新界面不会动,能称之为更新界面? 当老板一而再再而三地从你身边经过,发现还是这个进度的时候,也许就已经把你的工资划掉了,或者第二天你因为进办公室在椅子上坐下而被辞退。

那么下一步我们就要思考如何让它动起来。

思考动画

来看看启动动画大概是怎么样的:

开始是没有进度条的;

进度条会逐级移动、速度不一定相等。

基于以上两个条件,我设计了一种动画处理方式:

  • 构造分段的时长 (Duration),可以自由组合由多个时长;
  • 动画通过时长的数量决定每个时长最终的进度;
  • 每段时长控制起始值到结束值的间隔。

只有三个条件,简单到起飞,开动!(此时大约过去了 5 分钟)

实现动画

开局一个 AnimationController:

class _HomePageState extends State<HomePage> with SingleTickerProviderStateMixin {
  /// 巧用 late 初始化,节省代码量
  late final AnimationController _controller = AnimationController(vsync: this);

  /// 启动后等待的时长
  Duration get _waitingDuration => const Duration(seconds: 5);

  /// 分段的动画时长
  List<Duration> get _periodDurations {
    return <Duration>[
      const Duration(seconds: 5),
      const Duration(seconds: 10),
      const Duration(seconds: 4),
    ];
  }

  /// 当前进行到哪一个分段
  final ValueNotifier<int> _currentPeriod = ValueNotifier<int>(1);

接下来实现动画方法,采用了递归调用的方式,减少调用链的控制:

@override
void initState() {
  super.initState();
  // 等待对应秒数后,开始进度条动画
  Future.delayed(_waitingDuration).then((_) => _callAnimation());
}

Future<void> _callAnimation() async {
  // 取当前分段
  final Duration _currentDuration = _periodDurations[currentPeriod];
  // 准备下一分段
  currentPeriod++;
  // 如果到了最后一个分段,取空
  final Duration? _nextDuration = currentPeriod < _periodDurations.length ? _periodDurations.last : null;
  // 计算当前分段动画的结束值
  final double target = currentPeriod / _periodDurations.length;
  // 执行动画
  await _controller.animateTo(target, duration: _currentDuration);
  // 如果下一分段为空,即执行到了最后一个分段,重设当前分段,动画结束
  if (_nextDuration == null) {
    currentPeriod = 0;
    return;
  }
  // 否则调用下一分段的动画
  await _callAnimation();
}

以上短短几行代码,就完美的实现了进度条的动画操作。(此时大约过去了 8 分钟)

最后一步,将动画、分段二者与进度条绑定,在没进入分段前不展示进度条,在动画开始后展示对应的进度:

ValueListenableBuilder<int>(
  valueListenable: _currentPeriod,
  builder: (_, int period, __) {
    // 分段为0时,不展示
    if (period == 0) {
      return const SizedBox.shrink();
    }
    return DecoratedBox(
      decoration: BoxDecoration(
        border: Border.all(color: CupertinoColors.systemGrey),
        borderRadius: BorderRadius.circular(10),
      ),
      child: ClipRRect(
        borderRadius: BorderRadius.circular(10),
        child: AnimatedBuilder( // 使用 AnimatedBuilder,在动画进行时触发更新
          animation: _controller,
          builder: (_, __) => LinearProgressIndicator(
            value: _controller.value, // 将 controller 的值绑定给进度
            backgroundColor: CupertinoColors.lightBackgroundGray.withOpacity(.3),
            color: CupertinoColors.white,
            minHeight: 5,
          ),
        ),
      ),
    );
  },
)

大功告成,总共用时 10 分钟,让我们跑起来看看效果。(下图 22.1 M)

打包发布

发布正式版的 macOS 应用较为复杂,但我们可以打包给自己使用,只需要一行命令即可:flutter build macos。

成功后,产物将会输出在 build/macos/Build/Products/Release/touch_fish_on_macos.app,双击即可使用

结语

可能大多数人都没有想到,编写一个 Flutter 应用,跑在 macOS 上,能有这么简单。当然,看似短暂的 10 分钟并没有包括安装环境、搜索素材、提交到 git 的时间,但在这个时间范围内,完成相关的事情也是绰绰有余。

到此这篇关于利用Flutter制作一个摸鱼桌面版App的文章就介绍到这了,更多相关Flutter摸鱼App内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Flutter实现渐变色加描边字体效果

    目录 写在前面 内容 实现描边 实现渐变 一些调整 参考 写在前面 实现如下图的效果,这个数字的内部和外部都有渐变色. 内容 实现描边 在网上搜索一轮,可以看到通过用 Stack,来让两个 Text叠加,并对上一个 Text设置外部描边,就可以得到如下的效果. Stack( alignment: Alignment.center, children: [ Text( '100', style: TextStyle( fontSize: 40, fontWeight: FontWeight.bol

  • Flutter实现App功能引导页

    App功能介绍页,主要是由介绍app功能的几张图片和当前页指示符组成,如下效果 我们来一步一步实现上面的界面,左右滑动切换显示功能页,这个可以通过PageView来实现,底部的指示符半透明覆盖在PageView上,开发过Android同学知道可以用Framelayout布局来实现,Flutter上也有类似的控件Stack,我们先完成骨架代码 // An highlighted block void main() => runApp(App()); class App extends Statel

  • flutter 怎么实现app整体灰色效果

    Flutter 是 Google 开源的 UI 工具包,帮助开发者通过一套代码库高效构建多平台精美应用,支持移动.Web.桌面和嵌入式平台.Flutter 开源.免费,拥有宽松的开源协议,适合商业项目. 举国哀悼, 进入各种大厂的app也可以看到主色都变成灰色的了 作为程序员我们肯定会想怎么可以实现的, 我简单研究了10分钟, flutter中只要在整体外面套一个ShaderMask, 然后修改blendMode即可 核心代码: class MyApp extends StatelessWidg

  • Flutter自定义Appbar搜索框效果

    本文实例为大家分享了Flutter自定义Appbar搜索框效果的具体代码,供大家参考,具体内容如下 首先看一下实现本次实现的效果. 本来想直接偷懒从flutter pub上找个能用的使用起来,但是看了下发现都与目前ui效果相差很大,于是乎决定自己实现一个.整体的话比较简单,本来也是为了练手而做的. 为了方便处理statusbar的高度适配,于是乎直接依托于Appbar进行了实现,这样就可以不用处理状态栏适配了. class _HotWidgetState extends State<HotWid

  • Flutter Android应用启动白屏的解决方案

    目录 问题产生 如何解决 总结 问题产生 默认生成的flutter工程,在启动时候会白屏,设备性能越差,白屏时间越长.原生Android开发也会遇到类似问题,启动会产生白屏或者黑屏问题.在Android开发中通常是设置一个主题文件,这里不展开说. 如何解决 flutter其实已经提供了解决方案.打开flutter工程目录"\android\app\src\main"下的AndroidManifest.xml文件,可以看到如下内容: 这里英文的大意是:在flutter渲染第一帧之前,可以

  • Flutter自定义圆盘取色器

    本文实例为大家分享了Flutter自定义圆盘取色器的具体代码,供大家参考,具体内容如下 下面展示一些 内联代码片. 圆盘取色器 效果图 完整代码 import 'dart:math'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; class CircularColorFinder extends Sta

  • 利用Flutter制作一个摸鱼桌面版App

    目录 准备工作 开始敲代码 找到资源 思考布局 实现布局 思考动画 实现动画 结语 Win10商店上架了一款名为<摸鱼>的App,在下载打开之后,这个App会让你的电脑进入一个假更新的画面,让别人以为你的电脑正在升级,这时候你就可以休息一下,优雅地喝一杯咖啡.  顿时这个念头划过了我的脑海:好东西,但是我用的是 MacBook,不能用这个应用.但是貌似我可以自己写一个? 准备工作 年轻最需要的就是行动力,想到就干,尽管我此刻正在理顺 DevFest 的讲稿,但丝毫不妨碍我用 10 分钟写一个

  • 详解用flutter制作上班摸鱼应用

    网上最近看到了个摸鱼应用,还挺好玩的,我就自己用flutter写了一个. 之前我有用flutter制作过mobile应用,但是没有在desktop尝试过:毕竟2.0大更新,我这里就在这试手一下,并说说flutter的体验. 当前flutter环境 2.8 增加flutter desktop支持 (默认项目之存在ios,android项目包) flutter config --enable-<platform>-desktop 我这里是mac,因此platform=macos,详细看flutte

  • 利用Flutter制作经典贪吃蛇游戏

    目录 前言 使用 Flutter 作为游戏引擎 画蛇 2D 渲染的基础 创建蛇 填写列表 将蛇移动到下一个位置 添加运动和速度 添加控件 改变方向 吃东西和提高速度 在屏幕上显示食物 消耗和再生食物 检测碰撞并显示游戏结束对话框 添加一些收尾工作 重启游戏 显示分数 前言 Flutter (Channel stable, 2.10.3, on Microsoft Windows [Version 10.0.19044.1586], locale zh-CN) Android toolchain

  • 利用Python写个摸鱼监控进程

    目录 监控键盘 监控鼠标 记录监控日志 完整代码 总结 继打游戏.看视频等摸鱼行为被监控后,现在打工人离职的倾向也会被监控. 有网友爆料称知乎正在低调裁员,视频相关部门几乎要裁掉一半.而在知乎裁员的讨论区,有网友表示企业安装了行为感知系统,该系统可以提前获知员工跳槽念头. 而知乎在否认了裁员计划的同时,也声明从未安装使用过网上所说的行为感知系统,今后也不会启用类似软件工具. 因为此事,深信服被推上风口浪尖,舆论关注度越来越高. 一时间,“打工人太难了”“毫无隐私可言”的讨论层出不穷. 今天就带大

  • 基于Flutter制作一个火箭发射动画

    目录 总结 前言 北京时间10月16日0时23分,神舟十三号飞船成功发射,目前三名航天员已经顺利进驻空间站,开始为期6个月的“太空差旅”生活. 国家的航天技术的突飞猛进也让岛上码农很自豪,今天看 Flutter 的动画知识,看到了 AnimatedPositioned 这个组件,可以用于控制组件的相对位置移动.结合这个神舟十三号的发射,灵机一动,正好可以使用AnimatedPositioned 这个组件实现火箭发射动画.话不多说,先上效果! 效果说明 这里其实是两张图片叠加,一张是背景地球星空的

  • 利用java制作一个小的目录查询器的方法

    实例如下: import java.util.*; import javax.swing.*; import java.awt.*; import java.io.*; import java.awt.event.*; class MyWindow{ private Frame f1; private Button bt1; private TextField tx1; private TextArea tx2; MyWindow(){ init(); } public void init(){

  • Python利用PyQt5制作一个获取网络实时NBA数据并播报的GUI程序

    制作NBA数据爬虫 捋顺思路 我们在这里选择的是百度体育带来的数据,我们在百度当中直接搜索NBA跳转到网页,我们可以看到,百度已经为我们提供了相关的数据 我们点击进去后,可以发现这是一个非常简洁的网址 我们看一下这个地址栏,发现毫无规律https://tiyu.baidu.com/live/detail/576O5Zu955S35a2Q6IGM5Lia56%2Bu55CD6IGU6LWbI2Jhc2tldGJhbGwjMjAyMS0wNi0xMyPniLXlo6t2c%2BWspritq%2Bi

  • Python利用PyQt5制作一个获取网络实时数据NBA数据播报GUI功能

    制作NBA数据爬虫 捋顺思路 我们在这里选择的是百度体育带来的数据,我们在百度当中直接搜索NBA跳转到网页,我们可以看到,百度已经为我们提供了相关的数据 我们点击进去后,可以发现这是一个非常简洁的网址 我们看一下这个地址栏,发现毫无规律https://tiyu.baidu.com/live/detail/576O5Zu955S35a2Q6IGM5Lia56%2Bu55CD6IGU6LWbI2Jhc2tldGJhbGwjMjAyMS0wNi0xMyPniLXlo6t2c%2BWspritq%2Bi

  • 基于Python绘制一个摸鱼倒计时界面

    目录 前言 实现过程 前言 前段时间在微博看到一段摸鱼人的倒计时模板,感觉还挺有趣的. 于是我用了一小时的时间写了个页面出来 摸鱼办地址 (当然是摸鱼的时间啦). 模板是这样的: 摸鱼办公室 [摸鱼办公室]今天是 2021-11-30 星期二 你好,摸鱼人,工作再累,一定不要忘记摸鱼哦 ! 有事没事起身去茶水间去廊道去天台走走,别老在工位上坐着.多喝点水,钱是老板的,但命是自己的 ! 距离 周末 放假还有 2 天 距离 元旦 放假还有 3 天 距离 过年 放假还有 34 天 距离 清明节 放假还

  • 利用PyQt5制作一个豆瓣电影信息查看器

    制作一个查看器可以查看豆瓣前100名电影的信息,当然这个爬取信息比较简单.所以重点放在 QThread 多线程的应用上面. QThread 子线程是 PyQt5 自带的一个线程使用,因为如果使用 PyQt5 的主线程去做所有的事情.如果处理速度太慢的情况下主线程就会直接出现卡死状态. 网络信息提取的相关模块有下面这些,主要是一个获取 Html 信息,另一个解析 Html5 的页面信息. import requests # 网络请求库 from bs4 import BeautifulSoup #

随机推荐