Commit 7faee3e1 authored by Adam Barth's avatar Adam Barth

Add implicit animations to Input

Now the label animates from its inline position to above the text and
the focus highlight grows into place.
parent 61f82ee1
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/animation.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
...@@ -73,6 +74,9 @@ class Input extends StatefulComponent { ...@@ -73,6 +74,9 @@ class Input extends StatefulComponent {
_InputState createState() => new _InputState(); _InputState createState() => new _InputState();
} }
const Duration _kTransitionDuration = const Duration(milliseconds: 200);
const Curve _kTransitionCurve = Curves.ease;
class _InputState extends State<Input> { class _InputState extends State<Input> {
String _value; String _value;
EditableString _editableString; EditableString _editableString;
...@@ -139,21 +143,34 @@ class _InputState extends State<Input> { ...@@ -139,21 +143,34 @@ class _InputState extends State<Input> {
List<Widget> stackChildren = <Widget>[]; List<Widget> stackChildren = <Widget>[];
bool hasInlineLabel = config.labelText != null && !focused && !_value.isNotEmpty;
if (config.labelText != null) { if (config.labelText != null) {
TextStyle labelStyle = themeData.text.caption.copyWith(color: focused ? focusHighlightColor : themeData.hintColor); TextStyle labelStyle = hasInlineLabel ?
stackChildren.add(new Positioned( themeData.text.subhead.copyWith(color: themeData.hintColor) :
themeData.text.caption.copyWith(color: focused ? focusHighlightColor : themeData.hintColor);
double topPaddingIncrement = themeData.text.caption.fontSize + (config.isDense ? 4.0 : 8.0);
double top = topPadding;
if (hasInlineLabel)
top += topPaddingIncrement + textStyle.fontSize - labelStyle.fontSize;
stackChildren.add(new AnimatedPositioned(
left: 0.0, left: 0.0,
top: topPadding, top: top,
duration: _kTransitionDuration,
curve: _kTransitionCurve,
child: new Text(config.labelText, style: labelStyle) child: new Text(config.labelText, style: labelStyle)
)); ));
topPadding += labelStyle.fontSize + (config.isDense ? 4.0 : 8.0);
topPadding += topPaddingIncrement;
} }
if (config.hintText != null && _value.isEmpty) { if (config.hintText != null && _value.isEmpty && !hasInlineLabel) {
TextStyle hintStyle = textStyle.copyWith(color: themeData.hintColor); TextStyle hintStyle = themeData.text.subhead.copyWith(color: themeData.hintColor);
stackChildren.add(new Positioned( stackChildren.add(new Positioned(
left: 0.0, left: 0.0,
top: topPadding, top: topPadding + textStyle.fontSize - hintStyle.fontSize,
child: new Text(config.hintText, style: hintStyle) child: new Text(config.hintText, style: hintStyle)
)); ));
} }
...@@ -176,9 +193,11 @@ class _InputState extends State<Input> { ...@@ -176,9 +193,11 @@ class _InputState extends State<Input> {
} }
} }
stackChildren.add(new Container( stackChildren.add(new AnimatedContainer(
margin: margin, margin: margin,
padding: padding, padding: padding,
duration: _kTransitionDuration,
curve: _kTransitionCurve,
decoration: new BoxDecoration( decoration: new BoxDecoration(
border: new Border( border: new Border(
bottom: new BorderSide( bottom: new BorderSide(
......
...@@ -29,6 +29,25 @@ class BorderSide { ...@@ -29,6 +29,25 @@ class BorderSide {
/// A black border side of zero width. /// A black border side of zero width.
static const none = const BorderSide(width: 0.0); static const none = const BorderSide(width: 0.0);
BorderSide copyWith({
Color color,
double width
}) {
return new BorderSide(
color: color ?? this.color,
width: width ?? this.width
);
}
static BorderSide lerp(BorderSide a, BorderSide b, double t) {
assert(a != null);
assert(b != null);
return new BorderSide(
color: Color.lerp(a.color, b.color, t),
width: ui.lerpDouble(a.width, b.width, t)
);
}
bool operator ==(dynamic other) { bool operator ==(dynamic other) {
if (identical(this, other)) if (identical(this, other))
return true; return true;
...@@ -79,6 +98,30 @@ class Border { ...@@ -79,6 +98,30 @@ class Border {
return new EdgeDims.TRBL(top.width, right.width, bottom.width, left.width); return new EdgeDims.TRBL(top.width, right.width, bottom.width, left.width);
} }
Border scale(double t) {
return new Border(
top: top.copyWith(width: t * top.width),
right: right.copyWith(width: t * right.width),
bottom: bottom.copyWith(width: t * bottom.width),
left: left.copyWith(width: t * left.width)
);
}
static Border lerp(Border a, Border b, double t) {
if (a == null && b == null)
return null;
if (a == null)
return b.scale(t);
if (b == null)
return a.scale(1.0 - t);
return new Border(
top: BorderSide.lerp(a.top, b.top, t),
right: BorderSide.lerp(a.right, b.right, t),
bottom: BorderSide.lerp(a.bottom, b.bottom, t),
left: BorderSide.lerp(a.left, b.left, t)
);
}
bool operator ==(dynamic other) { bool operator ==(dynamic other) {
if (identical(this, other)) if (identical(this, other))
return true; return true;
...@@ -718,7 +761,7 @@ class BoxDecoration extends Decoration { ...@@ -718,7 +761,7 @@ class BoxDecoration extends Decoration {
return new BoxDecoration( return new BoxDecoration(
backgroundColor: Color.lerp(null, backgroundColor, factor), backgroundColor: Color.lerp(null, backgroundColor, factor),
backgroundImage: backgroundImage, backgroundImage: backgroundImage,
border: border, border: Border.lerp(null, border, factor),
borderRadius: ui.lerpDouble(null, borderRadius, factor), borderRadius: ui.lerpDouble(null, borderRadius, factor),
boxShadow: BoxShadow.lerpList(null, boxShadow, factor), boxShadow: BoxShadow.lerpList(null, boxShadow, factor),
gradient: gradient, gradient: gradient,
...@@ -740,7 +783,7 @@ class BoxDecoration extends Decoration { ...@@ -740,7 +783,7 @@ class BoxDecoration extends Decoration {
return new BoxDecoration( return new BoxDecoration(
backgroundColor: Color.lerp(a.backgroundColor, b.backgroundColor, t), backgroundColor: Color.lerp(a.backgroundColor, b.backgroundColor, t),
backgroundImage: b.backgroundImage, backgroundImage: b.backgroundImage,
border: b.border, border: Border.lerp(a.border, b.border, t),
borderRadius: ui.lerpDouble(a.borderRadius, b.borderRadius, t), borderRadius: ui.lerpDouble(a.borderRadius, b.borderRadius, t),
boxShadow: BoxShadow.lerpList(a.boxShadow, b.boxShadow, t), boxShadow: BoxShadow.lerpList(a.boxShadow, b.boxShadow, t),
gradient: b.gradient, gradient: b.gradient,
......
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