Commit a5a34d97 authored by Ian Hickson's avatar Ian Hickson

AnimatedDefaultTextStyle (#3324)

parent c40f4cfe
......@@ -5,6 +5,7 @@
import 'package:flutter/widgets.dart';
import 'colors.dart';
import 'constants.dart';
import 'debug.dart';
import 'ink_well.dart';
import 'material.dart';
......@@ -190,8 +191,9 @@ abstract class MaterialButtonState<T extends MaterialButton> extends State<T> {
child: contents
);
} else {
contents = new DefaultTextStyle(
contents = new AnimatedDefaultTextStyle(
style: style,
duration: kThemeChangeDuration,
child: contents
);
}
......
......@@ -5,6 +5,7 @@
import 'package:flutter/widgets.dart';
import 'colors.dart';
import 'constants.dart';
import 'debug.dart';
import 'icon.dart';
import 'icons.dart';
......@@ -102,8 +103,9 @@ class DrawerItem extends StatelessWidget {
new Flexible(
child: new Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: new DefaultTextStyle(
child: new AnimatedDefaultTextStyle(
style: _getTextStyle(themeData),
duration: kThemeChangeDuration,
child: child
)
)
......
......@@ -4,6 +4,7 @@
import 'package:flutter/widgets.dart';
import 'constants.dart';
import 'debug.dart';
import 'ink_well.dart';
import 'theme.dart';
......@@ -166,8 +167,9 @@ class ListItem extends StatelessWidget {
));
}
final Widget primaryLine = new DefaultTextStyle(
final Widget primaryLine = new AnimatedDefaultTextStyle(
style: _primaryTextStyle(context),
duration: kThemeChangeDuration,
child: title ?? new Container()
);
Widget center = primaryLine;
......@@ -177,8 +179,9 @@ class ListItem extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
primaryLine,
new DefaultTextStyle(
new AnimatedDefaultTextStyle(
style: _secondaryTextStyle(context),
duration: kThemeChangeDuration,
child: subtitle
)
]
......
......@@ -202,8 +202,9 @@ class _MaterialState extends State<Material> {
Color backgroundColor = _getBackgroundColor(context);
Widget contents = config.child;
if (contents != null) {
contents = new DefaultTextStyle(
contents = new AnimatedDefaultTextStyle(
style: config.textStyle ?? Theme.of(context).textTheme.body1,
duration: kThemeChangeDuration,
child: contents
);
}
......
......@@ -6,6 +6,7 @@ import 'dart:async';
import 'package:flutter/widgets.dart';
import 'constants.dart';
import 'divider.dart';
import 'icon.dart';
import 'icons.dart';
......@@ -90,8 +91,9 @@ class _PopupMenuItemState<T extends PopupMenuItem<dynamic>> extends State<T> {
if (!config.enabled)
style = style.copyWith(color: theme.disabledColor);
Widget item = new DefaultTextStyle(
Widget item = new AnimatedDefaultTextStyle(
style: style,
duration: kThemeChangeDuration,
child: new Baseline(
baseline: config.height - _kBaselineOffsetFromBottom,
child: buildChild()
......
......@@ -851,9 +851,9 @@ class _TabBarState<T> extends ScrollableState<TabBar<T>> implements TabBarSelect
indicatorColor = Colors.white;
}
TextStyle textStyle = themeData.primaryTextTheme.body2;
IconThemeData iconTheme = themeData.primaryIconTheme;
Color textColor = themeData.primaryTextTheme.body2.color.withAlpha(0xB2); // 70% alpha
final TextStyle textStyle = themeData.primaryTextTheme.body2;
final IconThemeData iconTheme = themeData.primaryIconTheme;
final Color textColor = themeData.primaryTextTheme.body2.color.withAlpha(0xB2); // 70% alpha
List<Widget> tabs = <Widget>[];
bool textAndIcons = false;
......
......@@ -48,6 +48,16 @@ class Matrix4Tween extends Tween<Matrix4> {
}
}
/// An interpolation between two [TextStyle]s.
///
/// This will not work well if the styles don't set the same fields.
class TextStyleTween extends Tween<TextStyle> {
TextStyleTween({ TextStyle begin, TextStyle end }) : super(begin: begin, end: end);
@override
TextStyle lerp(double t) => TextStyle.lerp(begin, end, t);
}
/// An abstract widget for building widgets that gradually change their
/// values over a period of time.
abstract class ImplicitlyAnimatedWidget extends StatefulWidget {
......@@ -504,3 +514,55 @@ class _AnimatedOpacityState extends AnimatedWidgetBaseState<AnimatedOpacity> {
);
}
}
/// Animated version of [DefaultTextStyle] which automatically
/// transitions the default text style (the text style to apply to
/// descendant [Text] widgets without explicit style) over a given
/// duration whenever the given style changes.
class AnimatedDefaultTextStyle extends ImplicitlyAnimatedWidget {
AnimatedDefaultTextStyle({
Key key,
this.child,
this.style,
Curve curve: Curves.linear,
Duration duration
}) : super(key: key, curve: curve, duration: duration) {
assert(style != null);
assert(child != null);
}
/// The widget below this widget in the tree.
final Widget child;
/// The target text style.
///
/// The text style must not be null.
final TextStyle style;
@override
_AnimatedDefaultTextStyleState createState() => new _AnimatedDefaultTextStyleState();
@override
void debugFillDescription(List<String> description) {
super.debugFillDescription(description);
'$style'.split('\n').forEach(description.add);
}
}
class _AnimatedDefaultTextStyleState extends AnimatedWidgetBaseState<AnimatedDefaultTextStyle> {
TextStyleTween _style;
@override
void forEachTween(TweenVisitor<dynamic> visitor) {
// TODO(ianh): Use constructor tear-offs when it becomes possible
_style = visitor(_style, config.style, (dynamic value) => new TextStyleTween(begin: value));
}
@override
Widget build(BuildContext context) {
return new DefaultTextStyle(
style: _style.evaluate(animation),
child: config.child
);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment