fresnel_android 0.1.0
fresnel_android: ^0.1.0 copied to clipboard
Android implementation of fresnel. Reports capabilities honestly and exposes Material 3 Expressive shape and motion tokens.
fresnel_android #
Android implementation of fresnel.
Apps depend on fresnel, which selects this package automatically on Android.
What it does #
Android has no Liquid Glass, and this package does not pretend otherwise. It has two jobs.
Report capabilities honestly. Without it the façade falls back to
GlassCapabilities.unsupported(), which claims reduce-motion and
increase-contrast are off rather than asking. Those flags are exactly the ones
the shader path has to honour itself — on the native path the OS does it for
us — so guessing them wrong is an accessibility failure, not a cosmetic one.
| Contract member | Android |
|---|---|
capabilities() |
native, via a Kotlin method channel |
buildNativeGlass() |
null — façade uses the shader |
buildNativeContainer() |
null — façade uses the shader |
renderSymbol() |
null — no SF Symbols |
Hand widgets the right tokens. AndroidGlassTokens carries the Material 3
Expressive corner scale and motion scheme, so a surface that cannot be glass
degrades to something that looks like Android instead of a flattened iOS
control.
import 'package:fresnel_android/fresnel_android.dart';
GlassSurface(
shape: AndroidGlassTokens.shapeExtraLarge,
child: const Text('Hello'),
)
How the accessibility flags are read #
- reduceMotion —
Settings.Global.TRANSITION_ANIMATION_SCALE == 0, withANIMATOR_DURATION_SCALEas a second probe because some OEM skins zero only one of the two. Android has noisReduceMotionEnabled, andAccessibilityManager.isEnabledis not a stand-in: it is true whenever any accessibility service runs, TalkBack included, and TalkBack users have not asked for animations to stop. - increaseContrast —
UiModeManager.getContrast() > 0on API 34+, the only public API for it. Below that, the securehigh_text_contrast_enabledkey (stable since API 21 but@hide) and colour inversion. - reduceTransparency — always false. Android has no such preference, and deriving one from "Remove animations" would make every surface opaque for users who only asked for stillness.
- osMajorVersion — deliberately not sent. The contract documents it as null off Apple platforms, and an API level in a field callers read as an Apple major version is worse than no value.
No permissions are declared; every setting read here is world-readable.
Why the tokens are what they are #
Material 3 Expressive replaced the duration/easing motion tokens with a
spring-based scheme in two families. Spatial springs move things and are
underdamped on purpose, so they overshoot — that overshoot is the
expressiveness. Effects springs change colour, opacity and elevation and are
critically damped, because an overshooting colour reads as a flicker.
AndroidGlassTokens exposes both, plus the emphasized duration/curve set for
the parts of Flutter's animation API that still want a fixed time.
The shape defaults follow suit: defaultShape is the 16dp large corner, and
shapeFull is a capsule with true circular arcs rather than a superellipse.
The squircle is Apple's corner; using it here would be the exact mistake this
package exists to avoid.
Layout #
lib/fresnel_android.dart FresnelAndroid, the platform impl
lib/src/android_glass_tokens.dart the M3 Expressive shape + motion tokens
android/build.gradle.kts
android/src/main/AndroidManifest.xml
android/src/main/kotlin/com/waqaralisiyal/fresnel_android/
FresnelAndroidPlugin.kt getCapabilities, and nothing else
License #
MIT. See LICENSE.