Flutter Vignette — Article Dark Mode
Flutter Vignette — Article Dark Mode
How to master the Article Dark Mode Vignette (by gskinner team)…Hmmm
All in one Flutter resource: https://flatteredwithflutter.com/dark-mode-vignette/
Summary
The web content provides a comprehensive tutorial on implementing dark and light mode themes with animated transitions in a Flutter application, following a challenge by Google to showcase Flutter's capabilities.
Abstract
The article "Flutter Vignette — Article Dark Mode" is a detailed guide that instructs developers on how to create an article UI with support for both dark and light themes in a Flutter app. The tutorial is structured into four key steps: replicating static article data, transitioning the navigation bar's background color using HSVColor, animating the article's floating action buttons (FABs) with the Transform widget, and masking the theme transition with custom widgets like WidgetMask and AnimatedSprite. The guide emphasizes the use of Flutter's widgets and animation capabilities to achieve a seamless and visually appealing transition between themes, enhancing user experience. It also provides access to the source code for each step, allowing developers to follow along and implement the features in their own projects.
Opinions
ImageIcon for icons that need to change based on the theme.HSVColor is recommended for background and foreground color transitions, suggesting it is a more intuitive approach for color manipulation.Transform widget is an effective way to animate FABs during theme transitions.WidgetMask and AnimatedSprite is presented as a crucial part of achieving a sophisticated masking effect for theme transitions.Flutter Vignette — Article Dark Mode
How to master the Article Dark Mode Vignette (by gskinner team)…Hmmm
All in one Flutter resource: https://flatteredwithflutter.com/dark-mode-vignette/
Other Vignettes :
For Flutter Interact ’19, Google challenged gskinner to showcase the Flutter framework’s capabilities to build beautiful apps.
What are we covering today…?
This tutorial is divided into 4 steps :

Data part is static and is taken from the original source code….
We replicate the data for an article (static data)….

App is a stack of navigation bar and article content. Top bar is a DarkInkBar widget and is comprised of

Icons in the nav bar are using this widget…This widget should be used, if you want to present diff. icons for light/dark mode…

Opacity is determined by an animation, which uses TweenSequence. Basically, our animation is a set of TweenSequenceItems and each has a weight that defines its percentage of the animation’s duration.
Article Content is the DarkInkContent widget and is comprised of
Here, is the Source Code for Step 1
We focus on the nav bar….While transitioning from one dark to light (or otherwise), we change the background color of our nav bar…..
Introducing HSVColor..
As per doc,
An HSVColor is represented in a parameter space that’s based on human perception of color in pigments (e.g. paint and printer’s ink).
For our background and foreground color, we have something like this..

Here, is the source code for Step 2…..
This step focuses on the animation of article’s FABs…
Our main app stack is now comprised of :

As we switch between themes, these FABs animate — when switching begins, the FABs move out of frame, and while its ending, the FABs show up…
This is done by Transform widget..

Under the transform property, we use Matrix4.translationValues. This takes in the parameters as (x, y, z)
Here, we supply animation value as y-axis parameter meaning the buttons will only shift in the y-direction….
Each FAB button is inside a separate animation and each animation is comprised of different sets of TweenSequenceItems…
Here, is the source code for Step 3…..
Probably the most important step…….
Wrap the article content(DarkInkContent) inside TransitionContainer (custom widget)…
This TransitionContainer has two important widgets (custom):
This widget basically extends Stack and tweaks how Stack renders its children…

Don’t get frightened with all the parameters, as they are basically what a Stack also needs….
For rendering the widget, we now need to override two important methods — createRenderObject (which takes in a RenderStack) and updateRenderObject (void method)…
Now if we look at the Stack implementation, we see

In the first method, instead of returning RenderStack, we render our custom widget RenderWidgetMask, which extends RenderStack….
RenderWidgetMask, uses a method called paintStack, wherein
// Skip painting the maskChild
final paintContent = (PaintingContext context, Offset offset) {
RenderBox child = (firstChild.parentData as StackParentData).nextSibling;while (child != null) {
final childParentData = child.parentData as StackParentData;// Here, we used lastChild, instead of child....
context.paintChild(lastChild, offset + childParentData.offset);
child = childParentData.nextSibling;
}
};In the below line, we skip painting the first child
RenderBox child = (firstChild.parentData as StackParentData).nextSibling;
context.pushOpacity(offset, 255, paintAll);where, 255 is the alpha argument to use when blending the painting
This widget extends AnimatedWidget…and needs to override the build method…

We need a parameter of type listenable (can be Animation
Inside the build method, we create a widget called Sprite (custom widget) and pass all the above parameters…
Sprite..
This widget, aims to get the size of the image dynamically frame by frame…and decides what part of image to render…
We use a widget called ImageInfo to get the size of the image…and other parameters….
ui.Image img = _imageInfo?.image;
int imgWidth = img.width;int frameW = widget.frameWidth, frameH = widget.frameHeight;Finally, we create a rectangle which draws a portion(rectangular) of the entire image, as the animation proceeds….This is the reason, we see the theme transition as a flow………
ui.Rect rect = ui.Rect.fromLTWH(
col * frameW * 1.0, // 0 to 9 * 360,
row * frameH * 1.0, // 0 to 3 * 720,
frameW * 1.0,
frameH * 1.0,
);return CustomPaint(painter: _SpritePainter(img, rect));Articles related to Flutter Desktop:

Syed Abdul BasitFrom tooltips to dialog boxes: Learn everything about implementing dynamic overlays in Flutter for a superior UI experience. 🎭
Maneesha ErandiNavigation Rail is a better way to switch the UI according to the screen size.
we train a model but most of the developer don’t know how to use it in the app.
Sumit KumarIntroduction
Exploring real-world projects is one of the most effective ways to learn and master Flutter. By examining these projects, you can gain…
Alexander Nguyen1-page. Well-formatted.