爆裂吧现实

不想死就早点睡

0%

1、前言

Flutter 所使用的 dart 语言具有垃圾回收机制,有垃圾回收就避免不了会内存泄漏。在 Android 平台上有个内存泄漏检测工具 LeakCanary ,它可以方便的在 debug 环境下检测当前页面是否泄漏。本文将会带你实现一个 flutter 可用的 LeakCanary,并讲述我是怎么用该工具检测出了 1.9.1 framework 上的两个泄漏。

Read more »

本文不讨论混合栈,只讨论纯 flutter 栈,代码基于 1.12.13,1.17 上 navigator 有做大量改动,不适用于在文章里面分析(源码量大),原理上相同。阅读本文前请先阅读 谈谈 flutter 的 build

一般来说,flutter 的页面都是由 Navigator 这个组件来组织的,一个页面对应一个 Route<T>。不过我看到许多业务方同学对于这个页面的理解有些偏差,比如以下几个问题:

  1. PageRoute<T> 的 build 函数是否会多次执行?(比如常用的 MaterialPageRoute<T> 里面的 build 函数)
  2. 当 push 了一个新的页面的时候,不在栈顶的页面根 widget 是否会重新执行 build 函数?
  3. 非栈顶页面是否会渲染?
  4. 非栈顶页面的 state 是否会保存?
Read more »

一、前言

flutter 中的 build(context) 算是我们开发 flutter 接触最多的一个函数,不管是大到页面,还是小到一个文本,都需要通过 build(context) 来构建,所以这个 build 函数的调用将会非常频繁。

所以对我们开发者来说,熟悉 build 函数的调用时机,了解某个操作会让哪些 widget 执行 build 是非常重要的。当然这不是一个立马可以学会的东西,因为不同组件的行为可能不一样,不过底层的原理都是相同的。

读完本文后,你将对 flutter 的 build、diff 复用机制 有个全局性的掌握,文章有点长,可以先收藏了慢慢看。

Read more »

  • 什么是手势冲突?它和 Listener 有啥区别?
  • Flutter 是怎么解决手势处理的?

如果你对上述问题的答案没有底,就需要来恶补 flutter 手势处理的规则了 😁

Read more »

本文分为两篇,讲述 flutter 中的指针事件和手势处理逻辑

一、Listener 和 GestureDetector

ListenerGestureDetecotor 是 flutter 中和手势事件相关常用的两个 widget 了,不过这两个还是有很大的差别的。

Listener 是一个纯粹的 指针事件(pointer event) 消费者,它能消费的事件有:onPointerDown, onPointerMove, onPointerUp, onPointerCancel..(这里忽略鼠标事件和不连续事件)*。它不识别任何手势,所以不存在两个 *Listener 竞争同一个指针事件的情况。

GestureDetector 就是处理手势的一个小部件了,它内部其实也是先通过 Listener 来监听基础的指针事件,然后把指针事件转化为不同的手势。因为手势会存在冲突,所以 GestureDetector 有个处理冲突的逻辑,比 Listener 复杂一些。

接下来我将会详细解析下 Listener 的一些处理逻辑,GestureDetector 的讲解放到下一篇文章中。

Read more »

前景概括

Flutter 是一个跨平台开发的工具,它极速的开发方式、Native 的表现性能、开源的代码等特点吸引了业界众多开发者的注意。不过由于 Flutter 处于萌芽发展阶段,还不是很完善,比如本文需要探讨的混合栈实现就是 Flutter 其中的一块短板,目前没有一套官方的解决方案,都是业界开发者在试水

这里简单介绍下 Flutter 的混合栈问题:Flutter 的界面是需要 Native 的容器来承载显示的,比如 Android 里面的 Activity,iOS 里面的 ViewController。现有的 app 不可能全部改成 flutter 实现,所以需要将 flutter 接入现有的 app 中,如果此时从 Native 页面跳转到 Flutter 页面,默认的方式会重新初始化一个 Flutter 实例运行,不会复用之前创建的 Flutter 实例

具体细节在之前的一篇混合栈文章 Flutter混合栈管理 里面讲述了

我之前开发过一个混合栈插件来解决 flutter 的混合开发问题,最后在使用的时候会碰到以下问题:

  • Flutter 的共享动画会失效 (Hero 动画)
  • 必须使用混合栈的 api 来打开跳转页面,无法使用系统的 Navigator

为了解决上述问题,需要重新设计 Flutter 混合栈插件,下面来探讨下怎么解决上述两个问题

Read more »

前景介绍

Flutter 是谷歌开发的一款可以跨平台开发的 UI 框架,它的原理接近于游戏引擎,目的在于统一 Android/iOS 两端开发,Flutter 页面有自己的栈,正常情况下,如果一个 app 完全由 Flutter 构成,那么只需要一个 FlutterView 即可。

上述方案只适用于一些新构建的 app,对于一些已有的 app,是不可能用 flutter 来重构的,成本太大,周期太长,所以这里需要实现一套 Native 页面栈和 Flutter 页面栈的管理方案,混合栈。

Read more »

Android 的插件化开发,这个坑非常深,其中有一个问题就是 bundle 和 host 的版本不一致性问题,如果 bundle 中 sdk 的版本和 host 中 sdk 版本不一致,就很有可能出现 api 兼容性问题,导致运行时 crash。

一开始会想:”让 host 和 bundle 中的版本号抽离成一个文件不就行了?

答案肯定是不行,因为这样只能让直接依赖的版本一致,不能让传递依赖的版本一致化

Read more »

Flutter 入门介绍

对于开发者而言,Flutter 是什么?他是用什么语言编写的?包含那几部分?是如何运行到设备上的?Flutter 工程和 Native 工程有何差别?支持热跟新吗?Flutter 界面是如何构建的…

这里对 Flutter 做一个大致方向的介绍,让你开始了解它

Read more »

简述

本文探讨下如何在 Android 上实现阻尼动画,首先 wiki 下阻尼的定义:是指任何振动系统在振动中,由于外界作用(如流体阻力、摩擦力等)和/或系统本身固有的原因引起的振动幅度逐渐下降的特性,也就是阻尼系统由两个子系统组成(振子系统、阻力系统),先前写过一篇 如何优雅地在Android上实现iOS的图片预览 ,就是一套阻尼动画的实现

不知道阻尼动画效果的同学可以去玩玩 iOS,iOS 的 UI 系统内置一套物理引擎,几乎所有的滚动界面都有阻尼动画效果(越界回弹)

在讨论阻尼动画之前,我先讲一下本人编写动画的历程,分为 3 个阶段(位置突变动画,位置不突变动画,速度不突变的动画

位置突变动画

此动画是 Android 里面最简单的动画,我们平常写的 ValueAnimator 动画、xml 动画,其实都是位置突变的动画,为什么叫它位置突变的动画呢,比如我要把一个 View 渐变出来,那么 alpha 数值应该是从 0 -> 1,但是假如在渐变动画还没有结束的时候(假如刚好播放到 0.5),我又想把 View 给渐隐掉,此时一般会播放一个 1 -> 0 的动画,这里就产生了位置突变效应(从 0.5 突变成了 1),造成的视觉效果就是视图闪动(等同于游戏里面的跳帧)

位置不突变动画

在上述动画的基础上,对于第二段的渐隐动画,我不从 1 -> 0 开始变化,我在播放渐隐动画前先获取 View 的透明度(0.5),然后让动画从 0.5 -> 0 开始变化(视觉上没有了闪动现象)

速度不突变动画

位置不突变动画一般都能满足要求了(系统自带的 ViewPropertyAnimator 就是位置不突变动画),但是为什么 iOS 的动画就看起来这么舒服,而安卓的动画看起来有点死板呢?这边就存在一个速度突变的问题

Read more »