Various documentation improvements. (#15071)
For example, mention the icon used for the drawer menu in the docs (this helps people writing unit tests); add DefaultAssetBundle sample code.
diff --git a/dev/bots/analyze-sample-code.dart b/dev/bots/analyze-sample-code.dart
index a82c44c..085c108 100644
--- a/dev/bots/analyze-sample-code.dart
+++ b/dev/bots/analyze-sample-code.dart
@@ -8,6 +8,8 @@
import 'package:path/path.dart' as path;
+// To run this: bin/cache/dart-sdk/bin/dart dev/bots/analyze-sample-code.dart
+
final String _flutterRoot = path.dirname(path.dirname(path.dirname(path.fromUri(Platform.script))));
final String _flutter = path.join(_flutterRoot, 'bin', Platform.isWindows ? 'flutter.bat' : 'flutter');
@@ -61,7 +63,6 @@
const String kDartDocPrefix = '///';
const String kDartDocPrefixWithSpace = '$kDartDocPrefix ';
-/// To run this: bin/cache/dart-sdk/bin/dart dev/bots/analyze-sample-code.dart
Future<Null> main() async {
final Directory temp = Directory.systemTemp.createTempSync('analyze_sample_code_');
int exitCode = 1;
@@ -136,8 +137,11 @@
}
buffer.add('// generated code');
buffer.add('import \'dart:async\';');
+ buffer.add('import \'dart:convert\';');
buffer.add('import \'dart:math\' as math;');
+ buffer.add('import \'dart:typed_data\';');
buffer.add('import \'dart:ui\' as ui;');
+ buffer.add('import \'package:flutter_test/flutter_test.dart\' hide TypeMatcher;');
for (FileSystemEntity file in flutterPackage.listSync(recursive: false, followLinks: false)) {
if (file is File && path.extension(file.path) == '.dart') {
buffer.add('');
@@ -158,6 +162,8 @@
dependencies:
flutter:
sdk: flutter
+ flutter_test:
+ sdk: flutter
''');
print('Found $sampleCodeSections sample code sections.');
final Process process = await Process.start(
@@ -257,7 +263,10 @@
if (block.first.startsWith('new ') || block.first.startsWith('const ')) {
_expressionId += 1;
sections.add(new Section(line, 'dynamic expression$_expressionId = ', block.toList(), ';'));
- } else if (block.first.startsWith('class ') || block.first.startsWith('const ')) {
+ } else if (block.first.startsWith('await ')) {
+ _expressionId += 1;
+ sections.add(new Section(line, 'Future<Null> expression$_expressionId() async { ', block.toList(), ' }'));
+ } else if (block.first.startsWith('class ')) {
sections.add(new Section(line, null, block.toList(), null));
} else {
final List<String> buffer = <String>[];
diff --git a/packages/flutter/lib/src/animation/animations.dart b/packages/flutter/lib/src/animation/animations.dart
index edfae74..41d51b0 100644
--- a/packages/flutter/lib/src/animation/animations.dart
+++ b/packages/flutter/lib/src/animation/animations.dart
@@ -112,9 +112,14 @@
}
}
-/// Implements most of the [Animation] interface, by deferring its behavior to a
-/// given [parent] Animation. To implement an [Animation] that proxies to a
-/// parent, this class plus implementing "T get value" is all that is necessary.
+/// Implements most of the [Animation] interface by deferring its behavior to a
+/// given [parent] Animation.
+///
+/// To implement an [Animation] that is driven by a parent, it is only necessary
+/// to mix in this class, implement [parent], and implement `T get value`.
+///
+/// To define a mapping from values in the range 0..1, consider subclassing
+/// [Tween] instead.
abstract class AnimationWithParentMixin<T> {
// This class is intended to be used as a mixin, and should not be
// extended directly.
diff --git a/packages/flutter/lib/src/material/app_bar.dart b/packages/flutter/lib/src/material/app_bar.dart
index 336811f..5dc56dc 100644
--- a/packages/flutter/lib/src/material/app_bar.dart
+++ b/packages/flutter/lib/src/material/app_bar.dart
@@ -162,12 +162,12 @@
/// A widget to display before the [title].
///
- /// If this is null and [automaticallyImplyLeading] is set to true, the [AppBar] will
- /// imply an appropriate widget. For example, if the [AppBar] is in a [Scaffold]
- /// that also has a [Drawer], the [Scaffold] will fill this widget with an
- /// [IconButton] that opens the drawer. If there's no [Drawer] and the parent
- /// [Navigator] can go back, the [AppBar] will use a [BackButton] that calls
- /// [Navigator.maybePop].
+ /// If this is null and [automaticallyImplyLeading] is set to true, the
+ /// [AppBar] will imply an appropriate widget. For example, if the [AppBar] is
+ /// in a [Scaffold] that also has a [Drawer], the [Scaffold] will fill this
+ /// widget with an [IconButton] that opens the drawer (using [Icons.menu]). If
+ /// there's no [Drawer] and the parent [Navigator] can go back, the [AppBar]
+ /// will use a [BackButton] that calls [Navigator.maybePop].
final Widget leading;
/// Controls whether we should try to imply the leading widget if null.
diff --git a/packages/flutter/lib/src/material/input_decorator.dart b/packages/flutter/lib/src/material/input_decorator.dart
index dfc4969..6da99db 100644
--- a/packages/flutter/lib/src/material/input_decorator.dart
+++ b/packages/flutter/lib/src/material/input_decorator.dart
@@ -1881,11 +1881,11 @@
/// [IconTheme] and therefore does not need to be explicitly given in the
/// icon widget.
///
- /// The suffix icon is not padded. To pad the leading edge of the prefix icon:
+ /// The suffix icon is not padded. To pad the leading edge of the suffix icon:
/// ```dart
- /// prefixIcon: new Padding(
+ /// suffixIcon: new Padding(
/// padding: const EdgeInsetsDirectional.only(start: 16.0),
- /// child: myIcon,
+ /// child: new Icon(Icons.search),
/// )
/// ```
///
diff --git a/packages/flutter/lib/src/material/tab_controller.dart b/packages/flutter/lib/src/material/tab_controller.dart
index 8241d31..9d0679b 100644
--- a/packages/flutter/lib/src/material/tab_controller.dart
+++ b/packages/flutter/lib/src/material/tab_controller.dart
@@ -17,8 +17,8 @@
/// a [TabController] and share it directly.
///
/// When the [TabBar] and [TabBarView] don't have a convenient stateful
-/// ancestor, a [TabController] can be shared with the [DefaultTabController]
-/// inherited widget.
+/// ancestor, a [TabController] can be shared by providing a
+/// [DefaultTabController] inherited widget.
///
/// ## Sample code
///
@@ -205,13 +205,14 @@
}
}
-/// The [TabController] for descendant widgets that don't specify one explicitly.
+/// The [TabController] for descendant widgets that don't specify one
+/// explicitly.
///
-/// DefaultTabController is an inherited widget that is used to share a
-/// TabController with a [TabBar] or a [TabBarView]. It's used when
-/// sharing an explicitly created TabController isn't convenient because
-/// the tab bar widgets are created by a stateless parent widget or by
-/// different parent widgets.
+/// [DefaultTabController] is an inherited widget that is used to share a
+/// [TabController] with a [TabBar] or a [TabBarView]. It's used when sharing an
+/// explicitly created [TabController] isn't convenient because the tab bar
+/// widgets are created by a stateless parent widget or by different parent
+/// widgets.
///
/// ```dart
/// class MyDemo extends StatelessWidget {
diff --git a/packages/flutter/lib/src/material/tabs.dart b/packages/flutter/lib/src/material/tabs.dart
index a9ea649..8fbf6c8 100644
--- a/packages/flutter/lib/src/material/tabs.dart
+++ b/packages/flutter/lib/src/material/tabs.dart
@@ -499,9 +499,9 @@
/// Typically created as the [AppBar.bottom] part of an [AppBar] and in
/// conjunction with a [TabBarView].
///
-/// If a [TabController] is not provided, then there must be a
-/// [DefaultTabController] ancestor. The tab controller's [TabController.length]
-/// must equal the length of the [tabs] list.
+/// If a [TabController] is not provided, then a [DefaultTabController] ancestor
+/// must be provided instead. The tab controller's [TabController.length] must
+/// equal the length of the [tabs] list.
///
/// Requires one of its ancestors to be a [Material] widget.
///
diff --git a/packages/flutter/lib/src/rendering/custom_paint.dart b/packages/flutter/lib/src/rendering/custom_paint.dart
index a6dc53b..5bd9f42 100644
--- a/packages/flutter/lib/src/rendering/custom_paint.dart
+++ b/packages/flutter/lib/src/rendering/custom_paint.dart
@@ -111,7 +111,9 @@
/// // Therefore we return false here. If we had fields (set
/// // from the constructor) then we would return true if any
/// // of them differed from the same fields on the oldDelegate.
+/// @override
/// bool shouldRepaint(Sky oldDelegate) => false;
+/// @override
/// bool shouldRebuildSemantics(Sky oldDelegate) => false;
/// }
/// ```
diff --git a/packages/flutter/lib/src/widgets/basic.dart b/packages/flutter/lib/src/widgets/basic.dart
index a7cad3a..b0ccc64 100644
--- a/packages/flutter/lib/src/widgets/basic.dart
+++ b/packages/flutter/lib/src/widgets/basic.dart
@@ -60,6 +60,10 @@
WrapAlignment,
WrapCrossAlignment;
+// Examples can assume:
+// class TestWidget extends StatelessWidget { @override Widget build(BuildContext context) => const Placeholder(); }
+// WidgetTester tester;
+
// BIDIRECTIONAL TEXT SUPPORT
/// A widget that determines the ambient directionality of text and
@@ -4457,6 +4461,47 @@
///
/// For example, used by [Image] to determine which bundle to use for
/// [AssetImage]s if no bundle is specified explicitly.
+///
+/// ## Sample code
+///
+/// This can be used in tests to override what the current asset bundle is, thus
+/// allowing specific resources to be injected into the widget under test.
+///
+/// For example, a test could create a test asset bundle like this:
+///
+/// ```dart
+/// class TestAssetBundle extends CachingAssetBundle {
+/// @override
+/// Future<ByteData> load(String key) async {
+/// if (key == 'resources/test')
+/// return new ByteData.view(new Uint8List.fromList(utf8.encode('Hello World!')).buffer);
+/// return null;
+/// }
+/// }
+/// ```
+///
+/// ...then wrap the widget under test with a [DefaultAssetBundle] using this
+/// bundle implementation:
+///
+/// ```dart
+/// await tester.pumpWidget(
+/// new MaterialApp(
+/// home: new DefaultAssetBundle(
+/// bundle: new TestAssetBundle(),
+/// child: new TestWidget(),
+/// ),
+/// ),
+/// );
+/// ```
+///
+/// Assuming that `TestWidget` uses [DefaultAssetBundle.of] to obtain its
+/// [AssetBundle], it will now see the [TestAssetBundle]'s "Hello World!" data
+/// when requesting the "resources/test" asset.
+///
+/// See also:
+///
+/// * [AssetBundle], the interface for asset bundles.
+/// * [rootBundle], the default default asset bundle.
class DefaultAssetBundle extends InheritedWidget {
/// Creates a widget that determines the default asset bundle for its descendants.
///
diff --git a/packages/flutter/lib/src/widgets/implicit_animations.dart b/packages/flutter/lib/src/widgets/implicit_animations.dart
index 1ae0e04..a083729 100644
--- a/packages/flutter/lib/src/widgets/implicit_animations.dart
+++ b/packages/flutter/lib/src/widgets/implicit_animations.dart
@@ -917,7 +917,7 @@
///
/// class LogoFadeState extends State<LogoFade> {
/// double opacityLevel = 1.0;
-///
+///
/// _changeOpacity() {
/// setState(() => opacityLevel = opacityLevel == 0 ? 1.0 : 0.0);
/// }