Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sound null safety #76

Merged
merged 34 commits into from
Nov 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
65a115d
Upgrade dependencies and fix lints
Nov 13, 2020
da5ba18
Remove unnecessary floats
Nov 13, 2020
4ead48c
Revert bottom_navy_bar version
Nov 13, 2020
5edd641
Tidy up to wrap in 80 chars
Nov 13, 2020
37d42bb
Use final where possible
Nov 13, 2020
de25751
Migrate package to null safety
Nov 13, 2020
f8a60d8
Add test for implicit dynamic
Nov 13, 2020
19e20fc
Remove lint rules that are already in pedantic
Nov 13, 2020
ea89d3c
Minor idiomatic changes
Nov 13, 2020
95657d8
Replace implicit dynamic lists with List<Object>
Nov 13, 2020
9bb6a8a
Merge branch 'master' into null_safety
Nov 14, 2020
5e9b735
Remove redundant null assertions
Nov 14, 2020
c710d06
Clean up naming
Nov 14, 2020
57d1122
Prefer declaring variables as final if possible
Nov 14, 2020
5211d68
Remove null test
Nov 14, 2020
6319b48
Fix spelling nit
Nov 14, 2020
cfd69ca
Cleaner null test syntax
Nov 14, 2020
3d9799e
Improve inclusive language
Nov 14, 2020
8677bbf
Grammar cleanup on property validation text
Nov 14, 2020
b8261f4
Make textStyle non-nullable
Nov 14, 2020
29c4a14
Improve inclusive language
Nov 14, 2020
49a70c3
Clean up naming
Nov 14, 2020
44036cf
Grammar cleanup on property validation text
Nov 14, 2020
109a501
Prefer final locals
Nov 14, 2020
5b209cc
Merge remote-tracking branch 'origin/master' into null_safety
Nov 14, 2020
72a0c05
Minor cleanup
Nov 14, 2020
0782772
Merge branch 'master' into null_safety
Nov 14, 2020
15832ea
Update version number to null safe recommendation
Nov 14, 2020
88dd663
Merge remote-tracking branch 'upstream/master'
Nov 24, 2020
853c53c
Merge pull request #1 from timsneath/null_safety
timsneath Nov 24, 2020
c56ca99
Tweak pubspec
Nov 24, 2020
f3a7d2c
Tweak pubspec
Nov 24, 2020
ce6fbff
Switch var to final/const
Nov 24, 2020
6360cd0
Tweak pubspec version
Nov 24, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions demo/lib/animated_input.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class AnimatedInput extends StatefulWidget {
final String text;
final InputBuilder builder;

AnimatedInput({this.text, this.builder});
AnimatedInput({required this.text, required this.builder});

@override
_AnimatedInputState createState() => _AnimatedInputState();
Expand All @@ -16,7 +16,7 @@ class _AnimatedInputState extends State<AnimatedInput>
with SingleTickerProviderStateMixin {
String _input = '';

AnimationController _controller;
late AnimationController _controller;

@override
void initState() {
Expand Down
6 changes: 3 additions & 3 deletions demo/lib/sync_demo.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class _SyncDemoState extends State<SyncDemo>
with SingleTickerProviderStateMixin {
double _scale = 0;
var group = AutoSizeGroup();
AnimationController _controller;
late AnimationController _controller;

@override
void initState() {
Expand Down Expand Up @@ -52,8 +52,8 @@ class _SyncDemoState extends State<SyncDemo>

@override
Widget build(BuildContext context) {
var group = AutoSizeGroup();
var text =
final group = AutoSizeGroup();
const text =
'These AutoSizeTexts fit the available space and synchronize their '
'text sizes.';
return Column(
Expand Down
2 changes: 1 addition & 1 deletion demo/lib/text_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class TextCard extends StatelessWidget {
final String title;
final Widget child;

TextCard({this.title, this.child});
TextCard({required this.title, required this.child});

@override
Widget build(BuildContext context) {
Expand Down
2 changes: 1 addition & 1 deletion demo/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: AutoSizeText Demo App
version: 1.0.0+2

environment:
sdk: ">=2.10.0 <3.0.0"
sdk: '>=2.12.0-0 <3.0.0'

dependencies:
flutter:
Expand Down
4 changes: 2 additions & 2 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name: example
description: AutoSizeText Example
description: AutoSizeText example

version: 1.0.0

environment:
sdk: ">=2.10.0 <3.0.0"
sdk: '>=2.12.0-0 <3.0.0'

dependencies:
flutter:
Expand Down
97 changes: 46 additions & 51 deletions lib/src/auto_size_text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ class AutoSizeText extends StatefulWidget {
/// If the [style] argument is null, the text will use the style from the
/// closest enclosing [DefaultTextStyle].
const AutoSizeText(
this.data, {
Key key,
String this.data, {
Key? key,
this.textKey,
this.style,
this.strutStyle,
Expand All @@ -32,15 +32,13 @@ class AutoSizeText extends StatefulWidget {
this.textScaleFactor,
this.maxLines,
this.semanticsLabel,
}) : assert(data != null,
'A non-null String must be provided to a AutoSizeText widget.'),
textSpan = null,
}) : textSpan = null,
super(key: key);

/// Creates a [AutoSizeText] widget with a [TextSpan].
const AutoSizeText.rich(
this.textSpan, {
Key key,
TextSpan this.textSpan, {
Key? key,
this.textKey,
this.style,
this.strutStyle,
Expand All @@ -59,32 +57,30 @@ class AutoSizeText extends StatefulWidget {
this.textScaleFactor,
this.maxLines,
this.semanticsLabel,
}) : assert(textSpan != null,
'A non-null TextSpan must be provided to a AutoSizeText.rich widget.'),
data = null,
}) : data = null,
super(key: key);

/// Sets the key for the resulting [Text] widget.
///
/// This allows you to find the actual `Text` widget built by `AutoSizeText`.
final Key textKey;
final Key? textKey;

/// The text to display.
///
/// This will be null if a [textSpan] is provided instead.
final String data;
final String? data;

/// The text to display as a [TextSpan].
///
/// This will be null if [data] is provided instead.
final TextSpan textSpan;
final TextSpan? textSpan;

/// If non-null, the style to use for this text.
///
/// If the style's "inherit" property is true, the style will be merged with
/// the closest enclosing [DefaultTextStyle]. Otherwise, the style will
/// replace the closest enclosing [DefaultTextStyle].
final TextStyle style;
final TextStyle? style;

// The default font size if none is specified.
static const double _defaultFontSize = 14;
Expand All @@ -99,7 +95,7 @@ class AutoSizeText extends StatefulWidget {
/// a font size.
///
/// See [StrutStyle] for details.
final StrutStyle strutStyle;
final StrutStyle? strutStyle;

/// The minimum text size constraint to be used when auto-sizing text.
///
Expand All @@ -125,17 +121,17 @@ class AutoSizeText extends StatefulWidget {
/// Predefines all the possible font sizes.
///
/// **Important:** PresetFontSizes have to be in descending order.
final List<double> presetFontSizes;
final List<double>? presetFontSizes;

/// Synchronizes the size of multiple [AutoSizeText]s.
///
/// If you want multiple [AutoSizeText]s to have the same text size, give all
/// of them the same [AutoSizeGroup] instance. All of them will have the
/// size of the smallest [AutoSizeText]
final AutoSizeGroup group;
final AutoSizeGroup? group;

/// How the text should be aligned horizontally.
final TextAlign textAlign;
final TextAlign? textAlign;

/// The directionality of the text.
///
Expand All @@ -150,20 +146,20 @@ class AutoSizeText extends StatefulWidget {
/// its left.
///
/// Defaults to the ambient [Directionality], if any.
final TextDirection textDirection;
final TextDirection? textDirection;

/// Used to select a font when the same Unicode character can
/// be rendered differently, depending on the locale.
///
/// It's rarely necessary to set this property. By default its value
/// is inherited from the enclosing app with `Localizations.localeOf(context)`.
final Locale locale;
final Locale? locale;

/// Whether the text should break at soft line breaks.
///
/// If false, the glyphs in the text will be positioned as if there was
/// unlimited horizontal space.
final bool softWrap;
final bool? softWrap;

/// Whether words which don't fit in one line should be wrapped.
///
Expand All @@ -174,11 +170,11 @@ class AutoSizeText extends StatefulWidget {
/// How visual overflow should be handled.
///
/// Defaults to retrieving the value from the nearest [DefaultTextStyle] ancestor.
final TextOverflow overflow;
final TextOverflow? overflow;

/// If the text is overflowing and does not fit its bounds, this widget is
/// displayed instead.
final Widget overflowReplacement;
final Widget? overflowReplacement;

/// The number of font pixels for each logical pixel.
///
Expand All @@ -190,7 +186,7 @@ class AutoSizeText extends StatefulWidget {
/// The value given to the constructor as textScaleFactor. If null, will
/// use the [MediaQueryData.textScaleFactor] obtained from the ambient
/// [MediaQuery], or 1.0 if there is no [MediaQuery] in scope.
final double textScaleFactor;
final double? textScaleFactor;

/// An optional maximum number of lines for the text to span, wrapping if necessary.
/// If the text exceeds the given number of lines, it will be resized according
Expand All @@ -203,7 +199,7 @@ class AutoSizeText extends StatefulWidget {
/// an explicit number for its [DefaultTextStyle.maxLines], then the
/// [DefaultTextStyle] value will take precedence. You can use a [RichText]
/// widget directly to entirely override the [DefaultTextStyle].
final int maxLines;
final int? maxLines;

/// An alternative semantics label for this text.
///
Expand All @@ -217,7 +213,7 @@ class AutoSizeText extends StatefulWidget {
/// ```dart
/// AutoSizeText(r'$$', semanticsLabel: 'Double dollars')
/// ```
final String semanticsLabel;
final String? semanticsLabel;

@override
_AutoSizeTextState createState() => _AutoSizeTextState();
Expand All @@ -228,9 +224,7 @@ class _AutoSizeTextState extends State<AutoSizeText> {
void initState() {
super.initState();

if (widget.group != null) {
widget.group._register(this);
}
widget.group?._register(this);
}

@override
Expand All @@ -249,10 +243,10 @@ class _AutoSizeTextState extends State<AutoSizeText> {
final defaultTextStyle = DefaultTextStyle.of(context);

var style = widget.style;
if (widget.style == null || widget.style.inherit) {
if (widget.style == null || widget.style!.inherit) {
style = defaultTextStyle.style.merge(widget.style);
}
if (style.fontSize == null) {
if (style!.fontSize == null) {
style = style.copyWith(fontSize: AutoSizeText._defaultFontSize);
}

Expand All @@ -267,21 +261,21 @@ class _AutoSizeTextState extends State<AutoSizeText> {
Widget text;

if (widget.group != null) {
widget.group._updateFontSize(this, fontSize);
text = _buildText(widget.group._fontSize, style, maxLines);
widget.group!._updateFontSize(this, fontSize);
text = _buildText(widget.group!._fontSize, style, maxLines);
} else {
text = _buildText(fontSize, style, maxLines);
}

if (widget.overflowReplacement != null && !textFits) {
return widget.overflowReplacement;
return widget.overflowReplacement!;
} else {
return text;
}
});
}

void _validateProperties(TextStyle style, int maxLines) {
void _validateProperties(TextStyle style, int? maxLines) {
assert(widget.overflow == null || widget.overflowReplacement == null,
'Either overflow or overflowReplacement must be null.');
assert(maxLines == null || maxLines > 0,
Expand All @@ -306,12 +300,13 @@ class _AutoSizeTextState extends State<AutoSizeText> {
'MaxFontSize must be a multiple of stepGranularity.');
}
} else {
assert(widget.presetFontSizes.isNotEmpty,
assert(widget.presetFontSizes!.isNotEmpty,
'PresetFontSizes must not be empty.');
}
}

List _calculateFontSize(BoxConstraints size, TextStyle style, int maxLines) {
List _calculateFontSize(
BoxConstraints size, TextStyle? style, int? maxLines) {
final span = TextSpan(
style: widget.textSpan?.style ?? style,
text: widget.textSpan?.text ?? widget.data,
Expand All @@ -325,11 +320,11 @@ class _AutoSizeTextState extends State<AutoSizeText> {
int left;
int right;

final presetFontSizes = widget.presetFontSizes?.reversed?.toList();
final presetFontSizes = widget.presetFontSizes?.reversed.toList();
if (presetFontSizes == null) {
final defaultFontSize =
style.fontSize.clamp(widget.minFontSize, widget.maxFontSize);
final defaultScale = defaultFontSize * userScale / style.fontSize;
final num defaultFontSize =
style!.fontSize!.clamp(widget.minFontSize, widget.maxFontSize);
final defaultScale = defaultFontSize * userScale / style.fontSize!;
if (_checkTextFits(span, defaultScale, maxLines, size)) {
return <Object>[defaultFontSize * userScale, true];
}
Expand All @@ -346,9 +341,9 @@ class _AutoSizeTextState extends State<AutoSizeText> {
final mid = (left + (right - left) / 2).floor();
double scale;
if (presetFontSizes == null) {
scale = mid * userScale * widget.stepGranularity / style.fontSize;
scale = mid * userScale * widget.stepGranularity / style!.fontSize!;
} else {
scale = presetFontSizes[mid] * userScale / style.fontSize;
scale = presetFontSizes[mid] * userScale / style!.fontSize!;
}
if (_checkTextFits(span, scale, maxLines, size)) {
left = mid + 1;
Expand All @@ -373,7 +368,7 @@ class _AutoSizeTextState extends State<AutoSizeText> {
}

bool _checkTextFits(
TextSpan text, double scale, int maxLines, BoxConstraints constraints) {
TextSpan text, double scale, int? maxLines, BoxConstraints constraints) {
if (!widget.wrapWords) {
final words = text.toPlainText().split(RegExp('\\s+'));

Expand All @@ -384,7 +379,7 @@ class _AutoSizeTextState extends State<AutoSizeText> {
),
textAlign: widget.textAlign ?? TextAlign.left,
textDirection: widget.textDirection ?? TextDirection.ltr,
textScaleFactor: scale ?? 1,
textScaleFactor: scale,
maxLines: words.length,
locale: widget.locale,
strutStyle: widget.strutStyle,
Expand All @@ -402,7 +397,7 @@ class _AutoSizeTextState extends State<AutoSizeText> {
text: text,
textAlign: widget.textAlign ?? TextAlign.left,
textDirection: widget.textDirection ?? TextDirection.ltr,
textScaleFactor: scale ?? 1,
textScaleFactor: scale,
maxLines: maxLines,
locale: widget.locale,
strutStyle: widget.strutStyle,
Expand All @@ -415,10 +410,10 @@ class _AutoSizeTextState extends State<AutoSizeText> {
textPainter.width > constraints.maxWidth);
}

Widget _buildText(double fontSize, TextStyle style, int maxLines) {
Widget _buildText(double fontSize, TextStyle style, int? maxLines) {
if (widget.data != null) {
return Text(
widget.data,
widget.data!,
key: widget.textKey,
style: style.copyWith(fontSize: fontSize),
strutStyle: widget.strutStyle,
Expand All @@ -433,7 +428,7 @@ class _AutoSizeTextState extends State<AutoSizeText> {
);
} else {
return Text.rich(
widget.textSpan,
widget.textSpan!,
key: widget.textKey,
style: style,
strutStyle: widget.strutStyle,
Expand All @@ -442,7 +437,7 @@ class _AutoSizeTextState extends State<AutoSizeText> {
locale: widget.locale,
softWrap: widget.softWrap,
overflow: widget.overflow,
textScaleFactor: fontSize / style.fontSize,
textScaleFactor: fontSize / style.fontSize!,
maxLines: maxLines,
semanticsLabel: widget.semanticsLabel,
);
Expand All @@ -456,7 +451,7 @@ class _AutoSizeTextState extends State<AutoSizeText> {
@override
void dispose() {
if (widget.group != null) {
widget.group._remove(this);
widget.group!._remove(this);
}
super.dispose();
}
Expand Down
Loading