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.
This commit is contained in:
Ian Hickson 2018-03-11 03:19:18 -07:00 committed by GitHub
parent 48bb5b7926
commit ded3905102
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 88 additions and 26 deletions

View file

@ -8,6 +8,8 @@ import 'dart:io';
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 @@ class Section {
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 @@ Future<Null> main() async {
}
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 @@ name: analyze_sample_code
dependencies:
flutter:
sdk: flutter
flutter_test:
sdk: flutter
''');
print('Found $sampleCodeSections sample code sections.');
final Process process = await Process.start(
@ -257,7 +263,10 @@ void processBlock(Line line, List<String> block, List<Section> sections) {
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>[];

View file

@ -112,9 +112,14 @@ class AlwaysStoppedAnimation<T> extends Animation<T> {
}
}
/// 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.

View file

@ -162,12 +162,12 @@ class AppBar extends StatefulWidget implements PreferredSizeWidget {
/// 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.

View file

@ -1881,11 +1881,11 @@ class InputDecoration {
/// [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),
/// )
/// ```
///

View file

@ -17,8 +17,8 @@ import 'constants.dart';
/// 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 @@ class _TabControllerScope extends InheritedWidget {
}
}
/// 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 {

View file

@ -499,9 +499,9 @@ class _TabBarScrollController extends ScrollController {
/// 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.
///

View file

@ -111,7 +111,9 @@ typedef List<CustomPainterSemantics> SemanticsBuilderCallback(Size size);
/// // 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;
/// }
/// ```

View file

@ -60,6 +60,10 @@ export 'package:flutter/rendering.dart' show
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 @@ class RawImage extends LeafRenderObjectWidget {
///
/// 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.
///

View file

@ -917,7 +917,7 @@ class _AnimatedPositionedDirectionalState extends AnimatedWidgetBaseState<Animat
///
/// class LogoFadeState extends State<LogoFade> {
/// double opacityLevel = 1.0;
///
///
/// _changeOpacity() {
/// setState(() => opacityLevel = opacityLevel == 0 ? 1.0 : 0.0);
/// }