Quellcode durchsuchen

add type badge for item

cjl_macbook vor 6 Jahren
Ursprung
Commit
954a842e14

+ 4
- 4
README.md Datei anzeigen

@@ -24,7 +24,7 @@ API incompatibility
24 24
 
25 25
 because support video, so the ImagePathEntity and ImageEntity rename to AssetPathEntity and AssetEntity.
26 26
 
27
-so PhotoPicker.pickImage return type will change to List<AssetEntity>
27
+so PhotoPicker.pickImage return type will change to `List<AssetEntity>`
28 28
 
29 29
 ## install
30 30
 
@@ -44,7 +44,7 @@ import 'package:photo_manager/photo_manager.dart';
44 44
 
45 45
 ```dart
46 46
 void _pickImage() async {
47
-    List<AssetEntity> imgList = await PhotoPicker.pickImage(
47
+    List<AssetEntity> imgList = await PhotoPicker.pickAsset(
48 48
       context: context,
49 49
       // BuildContext requied
50 50
 
@@ -121,8 +121,8 @@ Because the album is a privacy privilege, you need user permission to access it.
121 121
 like next
122 122
 
123 123
 ```plist
124
-	<key>NSPhotoLibraryUsageDescription</key>
125
-    <string>App need your agree, can visit your album</string>
124
+<key>NSPhotoLibraryUsageDescription</key>
125
+<string>App need your agree, can visit your album</string>
126 126
 ```
127 127
 
128 128
 xcode like image

+ 7
- 6
example/lib/main.dart Datei anzeigen

@@ -31,9 +31,9 @@ class _MyHomePageState extends State<MyHomePage> with LoadingDelegate {
31 31
   String currentSelected = "";
32 32
 
33 33
   void _pickImage() async {
34
-    List<AssetEntity> imgList = await PhotoPicker.pickImage(
34
+    List<AssetEntity> imgList = await PhotoPicker.pickAsset(
35
+      // BuildContext required
35 36
       context: context,
36
-      // BuildContext requied
37 37
 
38 38
       /// The following are optional parameters.
39 39
       themeColor: Colors.green,
@@ -50,7 +50,7 @@ class _MyHomePageState extends State<MyHomePage> with LoadingDelegate {
50 50
       // max picker image count
51 51
       provider: I18nProvider.chinese,
52 52
       // i18n provider ,default is chinese. , you can custom I18nProvider or use ENProvider()
53
-      rowCount: 5,
53
+      rowCount: 3,
54 54
       // item row count
55 55
       textColor: Colors.white,
56 56
       // text color
@@ -61,10 +61,11 @@ class _MyHomePageState extends State<MyHomePage> with LoadingDelegate {
61 61
       checkBoxBuilderDelegate: DefaultCheckBoxBuilderDelegate(
62 62
         activeColor: Colors.white,
63 63
         unselectedColor: Colors.white,
64
-      ), // default is DefaultCheckBoxBuilderDelegate ,or you make custom delegate to create checkbox
64
+      ),
65
+      // default is DefaultCheckBoxBuilderDelegate ,or you make custom delegate to create checkbox
65 66
 
66
-      loadingDelegate:
67
-          this, // if you want to build custom loading widget,extends LoadingDelegate, [see example/lib/main.dart]
67
+      loadingDelegate: this,
68
+      // if you want to build custom loading widget,extends LoadingDelegate, [see example/lib/main.dart]
68 69
     );
69 70
 
70 71
     if (imgList == null) {

+ 49
- 4
lib/photo.dart Datei anzeigen

@@ -3,6 +3,7 @@ library photo;
3 3
 import 'dart:async';
4 4
 
5 5
 import 'package:flutter/material.dart';
6
+import 'package:photo/src/delegate/badge_delegate.dart';
6 7
 import 'package:photo/src/delegate/checkbox_builder_delegate.dart';
7 8
 import 'package:photo/src/delegate/loading_delegate.dart';
8 9
 import 'package:photo/src/delegate/sort_delegate.dart';
@@ -30,25 +31,67 @@ class PhotoPicker {
30 31
 
31 32
   static const String rootRouteName = "photo_picker_image";
32 33
 
34
+  /// use new method [pickAsset]
35
+  ///
36
+  /// This method will be removed in the future.
37
+  @deprecated
38
+  static Future<List<AssetEntity>> pickImage({
39
+    @required BuildContext context,
40
+    int rowCount = 4,
41
+    int maxSelected = 9,
42
+    double padding = 0.5,
43
+    double itemRadio = 1.0,
44
+    Color themeColor,
45
+    Color dividerColor,
46
+    Color textColor,
47
+    Color disableColor,
48
+    int thumbSize = 64,
49
+    I18nProvider provider = I18nProvider.chinese,
50
+    SortDelegate sortDelegate,
51
+    CheckBoxBuilderDelegate checkBoxBuilderDelegate,
52
+    LoadingDelegate loadingDelegate,
53
+  }) {
54
+    return pickAsset(
55
+      context: context,
56
+      rowCount: rowCount,
57
+      maxSelected: maxSelected,
58
+      padding: padding,
59
+      itemRadio: itemRadio,
60
+      themeColor: themeColor,
61
+      dividerColor: dividerColor,
62
+      textColor: textColor,
63
+      disableColor: disableColor,
64
+      thumbSize: thumbSize,
65
+      provider: provider,
66
+      sortDelegate: sortDelegate,
67
+      checkBoxBuilderDelegate: checkBoxBuilderDelegate,
68
+      loadingDelegate: loadingDelegate,
69
+    );
70
+  }
71
+
33 72
   /// 没有授予权限的时候,会开启一个dialog去帮助用户去应用设置页面开启权限
34
-  /// 确定开启设置页面,取消关闭弹窗
73
+  /// 确定开启设置页面,取消关闭弹窗,无论选择什么,返回值都是null
35 74
   ///
36 75
   ///
37 76
   /// 当用户给予权限后
38 77
   ///
39 78
   ///   当用户确定时,返回一个图片[AssetEntity]列表
40 79
   ///
41
-  ///   当用户取消时
80
+  ///   当用户取消时返回一个空数组
81
+  ///
82
+  /// 关于参数可以查看readme文档介绍
42 83
   ///
43 84
   /// if user not grand permission, then return null and show a dialog to help user open setting.
44
-  /// sure is open setting cancel ,cancel to dismiss dialog
85
+  /// sure is open setting cancel ,cancel to dismiss dialog, return null
45 86
   ///
46 87
   /// when user give permission.
47 88
   ///
48 89
   ///   when user sure , return a [AssetEntity] of [List]
49 90
   ///
50 91
   ///   when user cancel selected,result is empty list
51
-  static Future<List<AssetEntity>> pickImage({
92
+  ///
93
+  /// params see readme.md
94
+  static Future<List<AssetEntity>> pickAsset({
52 95
     @required BuildContext context,
53 96
     int rowCount = 4,
54 97
     int maxSelected = 9,
@@ -63,6 +106,7 @@ class PhotoPicker {
63 106
     SortDelegate sortDelegate,
64 107
     CheckBoxBuilderDelegate checkBoxBuilderDelegate,
65 108
     LoadingDelegate loadingDelegate,
109
+    BadgeDelegate badgeDelegate = const DefaultBadgeDelegate(),
66 110
   }) {
67 111
     assert(provider != null, "provider must be not null");
68 112
     assert(context != null, "context must be not null");
@@ -90,6 +134,7 @@ class PhotoPicker {
90 134
       sortDelegate: sortDelegate,
91 135
       checkBoxBuilderDelegate: checkBoxBuilderDelegate,
92 136
       loadingDelegate: loadingDelegate,
137
+      badgeDelegate: badgeDelegate,
93 138
     );
94 139
 
95 140
     return PhotoPicker()._pickImage(

+ 47
- 0
lib/src/delegate/badge_delegate.dart Datei anzeigen

@@ -0,0 +1,47 @@
1
+import 'package:flutter/material.dart';
2
+import 'package:photo_manager/photo_manager.dart';
3
+
4
+abstract class BadgeDelegate {
5
+  const BadgeDelegate();
6
+
7
+  Widget buildBadge(BuildContext context, AssetType type);
8
+}
9
+
10
+class DefaultBadgeDelegate extends BadgeDelegate {
11
+  final AlignmentGeometry alignment;
12
+
13
+  const DefaultBadgeDelegate({
14
+    this.alignment = Alignment.topLeft,
15
+  });
16
+
17
+  @override
18
+  Widget buildBadge(BuildContext context, AssetType type) {
19
+    if (type == AssetType.video) {
20
+      return Padding(
21
+        padding: const EdgeInsets.only(
22
+          top: 2.0,
23
+          left: 2.0,
24
+        ),
25
+        child: Align(
26
+          alignment: alignment,
27
+          child: Container(
28
+            decoration: BoxDecoration(
29
+              color: Theme.of(context).primaryColor,
30
+              borderRadius: BorderRadius.circular(3.0),
31
+            ),
32
+            child: Text(
33
+              "video",
34
+              style: const TextStyle(
35
+                fontSize: 12.0,
36
+                color: Colors.white,
37
+              ),
38
+            ),
39
+            padding: const EdgeInsets.all(4.0),
40
+          ),
41
+        ),
42
+      );
43
+    }
44
+
45
+    return Container();
46
+  }
47
+}

+ 4
- 0
lib/src/entity/options.dart Datei anzeigen

@@ -1,4 +1,5 @@
1 1
 import 'package:flutter/material.dart';
2
+import 'package:photo/src/delegate/badge_delegate.dart';
2 3
 import 'package:photo/src/delegate/checkbox_builder_delegate.dart';
3 4
 import 'package:photo/src/delegate/loading_delegate.dart';
4 5
 import 'package:photo/src/delegate/sort_delegate.dart';
@@ -28,6 +29,8 @@ class Options {
28 29
 
29 30
   final LoadingDelegate loadingDelegate;
30 31
 
32
+  final BadgeDelegate badgeDelegate;
33
+
31 34
   const Options({
32 35
     this.rowCount,
33 36
     this.maxSelected,
@@ -41,5 +44,6 @@ class Options {
41 44
     this.sortDelegate,
42 45
     this.checkBoxBuilderDelegate,
43 46
     this.loadingDelegate,
47
+    this.badgeDelegate,
44 48
   });
45 49
 }

+ 41
- 19
lib/src/ui/page/photo_main_page.dart Datei anzeigen

@@ -1,6 +1,7 @@
1 1
 import 'dart:typed_data';
2 2
 
3 3
 import 'package:flutter/material.dart';
4
+import 'package:photo/src/delegate/badge_delegate.dart';
4 5
 import 'package:photo/src/delegate/loading_delegate.dart';
5 6
 import 'package:photo/src/engine/lru_cache.dart';
6 7
 import 'package:photo/src/entity/options.dart';
@@ -190,19 +191,22 @@ class _PhotoMainPageState extends State<PhotoMainPage>
190 191
 
191 192
   Widget _buildItem(BuildContext context, int index) {
192 193
     var data = list[index];
193
-    return GestureDetector(
194
-      onTap: () => _onItemClick(data, index),
195
-      child: Stack(
196
-        children: <Widget>[
197
-          ImageItem(
198
-            entity: data,
199
-            themeColor: themeColor,
200
-            size: options.thumbSize,
201
-            loadingDelegate: options.loadingDelegate,
202
-          ),
203
-          _buildMask(containsEntity(data)),
204
-          _buildSelected(data),
205
-        ],
194
+    return RepaintBoundary(
195
+      child: GestureDetector(
196
+        onTap: () => _onItemClick(data, index),
197
+        child: Stack(
198
+          children: <Widget>[
199
+            ImageItem(
200
+              entity: data,
201
+              themeColor: themeColor,
202
+              size: options.thumbSize,
203
+              loadingDelegate: options.loadingDelegate,
204
+              badgeDelegate: options.badgeDelegate,
205
+            ),
206
+            _buildMask(containsEntity(data)),
207
+            _buildSelected(data),
208
+          ],
209
+        ),
206 210
       ),
207 211
     );
208 212
   }
@@ -491,19 +495,22 @@ class ImageItem extends StatelessWidget {
491 495
 
492 496
   final LoadingDelegate loadingDelegate;
493 497
 
498
+  final BadgeDelegate badgeDelegate;
499
+
494 500
   const ImageItem({
495 501
     Key key,
496 502
     this.entity,
497 503
     this.themeColor,
498 504
     this.size = 64,
499 505
     this.loadingDelegate,
506
+    this.badgeDelegate,
500 507
   }) : super(key: key);
501 508
 
502 509
   @override
503 510
   Widget build(BuildContext context) {
504 511
     var thumb = ImageLruCache.getData(entity, size);
505 512
     if (thumb != null) {
506
-      return _buildImageItem(thumb);
513
+      return _buildImageItem(context, thumb);
507 514
     }
508 515
 
509 516
     return FutureBuilder<Uint8List>(
@@ -513,22 +520,37 @@ class ImageItem extends StatelessWidget {
513 520
         if (snapshot.connectionState == ConnectionState.done &&
514 521
             futureData != null) {
515 522
           ImageLruCache.setData(entity, size, futureData);
516
-          return _buildImageItem(futureData);
523
+          return _buildImageItem(context, futureData);
517 524
         }
518 525
         return Center(
519
-          child:
520
-              loadingDelegate.buildPreviewLoading(context, entity, themeColor),
526
+          child: loadingDelegate.buildPreviewLoading(
527
+            context,
528
+            entity,
529
+            themeColor,
530
+          ),
521 531
         );
522 532
       },
523 533
     );
524 534
   }
525 535
 
526
-  Widget _buildImageItem(Uint8List data) {
527
-    return Image.memory(
536
+  Widget _buildImageItem(BuildContext context, Uint8List data) {
537
+    var image = Image.memory(
528 538
       data,
529 539
       width: double.infinity,
530 540
       height: double.infinity,
531 541
       fit: BoxFit.cover,
532 542
     );
543
+    var badge = badgeDelegate?.buildBadge(context, entity.type);
544
+    if (badge == null) {
545
+      return image;
546
+    }
547
+    return Stack(
548
+      children: <Widget>[
549
+        image,
550
+        IgnorePointer(
551
+          child: badge,
552
+        ),
553
+      ],
554
+    );
533 555
   }
534 556
 }

+ 27
- 25
lib/src/ui/page/photo_preview_page.dart Datei anzeigen

@@ -267,32 +267,34 @@ class _PhotoPreviewPageState extends State<PhotoPreviewPage> {
267 267
 
268 268
   Widget _buildThumbItem(BuildContext context, int index) {
269 269
     var item = previewList[index];
270
-    return GestureDetector(
271
-      onTap: () => changeSelected(item, index),
272
-      child: Container(
273
-        width: 80.0,
274
-        child: Stack(
275
-          children: <Widget>[
276
-            ImageItem(
277
-              themeColor: themeColor,
278
-              entity: item,
279
-              size: options.thumbSize,
280
-              loadingDelegate: options.loadingDelegate,
281
-            ),
282
-            IgnorePointer(
283
-              child: StreamBuilder(
284
-                stream: pageStream,
285
-                builder: (BuildContext context, AsyncSnapshot snapshot) {
286
-                  if (selectedList.contains(item)) {
287
-                    return Container();
288
-                  }
289
-                  return Container(
290
-                    color: Colors.white.withOpacity(0.5),
291
-                  );
292
-                },
270
+    return RepaintBoundary(
271
+      child: GestureDetector(
272
+        onTap: () => changeSelected(item, index),
273
+        child: Container(
274
+          width: 80.0,
275
+          child: Stack(
276
+            children: <Widget>[
277
+              ImageItem(
278
+                themeColor: themeColor,
279
+                entity: item,
280
+                size: options.thumbSize,
281
+                loadingDelegate: options.loadingDelegate,
293 282
               ),
294
-            ),
295
-          ],
283
+              IgnorePointer(
284
+                child: StreamBuilder(
285
+                  stream: pageStream,
286
+                  builder: (BuildContext context, AsyncSnapshot snapshot) {
287
+                    if (selectedList.contains(item)) {
288
+                      return Container();
289
+                    }
290
+                    return Container(
291
+                      color: Colors.white.withOpacity(0.5),
292
+                    );
293
+                  },
294
+                ),
295
+              ),
296
+            ],
297
+          ),
296 298
         ),
297 299
       ),
298 300
     );

+ 250
- 5
pubspec.lock Datei anzeigen

@@ -1,6 +1,20 @@
1 1
 # Generated by pub
2 2
 # See https://www.dartlang.org/tools/pub/glossary#lockfile
3 3
 packages:
4
+  analyzer:
5
+    dependency: transitive
6
+    description:
7
+      name: analyzer
8
+      url: "https://pub.flutter-io.cn"
9
+    source: hosted
10
+    version: "0.32.4"
11
+  args:
12
+    dependency: transitive
13
+    description:
14
+      name: args
15
+      url: "https://pub.flutter-io.cn"
16
+    source: hosted
17
+    version: "1.5.0"
4 18
   async:
5 19
     dependency: transitive
6 20
     description:
@@ -29,6 +43,27 @@ packages:
29 43
       url: "https://pub.flutter-io.cn"
30 44
     source: hosted
31 45
     version: "1.14.11"
46
+  convert:
47
+    dependency: transitive
48
+    description:
49
+      name: convert
50
+      url: "https://pub.flutter-io.cn"
51
+    source: hosted
52
+    version: "2.0.2"
53
+  crypto:
54
+    dependency: transitive
55
+    description:
56
+      name: crypto
57
+      url: "https://pub.flutter-io.cn"
58
+    source: hosted
59
+    version: "2.0.6"
60
+  csslib:
61
+    dependency: transitive
62
+    description:
63
+      name: csslib
64
+      url: "https://pub.flutter-io.cn"
65
+    source: hosted
66
+    version: "0.14.5"
32 67
   flutter:
33 68
     dependency: "direct main"
34 69
     description: flutter
@@ -39,6 +74,83 @@ packages:
39 74
     description: flutter
40 75
     source: sdk
41 76
     version: "0.0.0"
77
+  front_end:
78
+    dependency: transitive
79
+    description:
80
+      name: front_end
81
+      url: "https://pub.flutter-io.cn"
82
+    source: hosted
83
+    version: "0.1.4"
84
+  glob:
85
+    dependency: transitive
86
+    description:
87
+      name: glob
88
+      url: "https://pub.flutter-io.cn"
89
+    source: hosted
90
+    version: "1.1.7"
91
+  html:
92
+    dependency: transitive
93
+    description:
94
+      name: html
95
+      url: "https://pub.flutter-io.cn"
96
+    source: hosted
97
+    version: "0.13.3+3"
98
+  http:
99
+    dependency: transitive
100
+    description:
101
+      name: http
102
+      url: "https://pub.flutter-io.cn"
103
+    source: hosted
104
+    version: "0.11.3+17"
105
+  http_multi_server:
106
+    dependency: transitive
107
+    description:
108
+      name: http_multi_server
109
+      url: "https://pub.flutter-io.cn"
110
+    source: hosted
111
+    version: "2.0.5"
112
+  http_parser:
113
+    dependency: transitive
114
+    description:
115
+      name: http_parser
116
+      url: "https://pub.flutter-io.cn"
117
+    source: hosted
118
+    version: "3.1.3"
119
+  io:
120
+    dependency: transitive
121
+    description:
122
+      name: io
123
+      url: "https://pub.flutter-io.cn"
124
+    source: hosted
125
+    version: "0.3.3"
126
+  js:
127
+    dependency: transitive
128
+    description:
129
+      name: js
130
+      url: "https://pub.flutter-io.cn"
131
+    source: hosted
132
+    version: "0.6.1+1"
133
+  json_rpc_2:
134
+    dependency: transitive
135
+    description:
136
+      name: json_rpc_2
137
+      url: "https://pub.flutter-io.cn"
138
+    source: hosted
139
+    version: "2.0.9"
140
+  kernel:
141
+    dependency: transitive
142
+    description:
143
+      name: kernel
144
+      url: "https://pub.flutter-io.cn"
145
+    source: hosted
146
+    version: "0.3.4"
147
+  logging:
148
+    dependency: transitive
149
+    description:
150
+      name: logging
151
+      url: "https://pub.flutter-io.cn"
152
+    source: hosted
153
+    version: "0.11.3+2"
42 154
   matcher:
43 155
     dependency: transitive
44 156
     description:
@@ -53,6 +165,41 @@ packages:
53 165
       url: "https://pub.flutter-io.cn"
54 166
     source: hosted
55 167
     version: "1.1.6"
168
+  mime:
169
+    dependency: transitive
170
+    description:
171
+      name: mime
172
+      url: "https://pub.flutter-io.cn"
173
+    source: hosted
174
+    version: "0.9.6+2"
175
+  multi_server_socket:
176
+    dependency: transitive
177
+    description:
178
+      name: multi_server_socket
179
+      url: "https://pub.flutter-io.cn"
180
+    source: hosted
181
+    version: "1.0.2"
182
+  node_preamble:
183
+    dependency: transitive
184
+    description:
185
+      name: node_preamble
186
+      url: "https://pub.flutter-io.cn"
187
+    source: hosted
188
+    version: "1.4.4"
189
+  package_config:
190
+    dependency: transitive
191
+    description:
192
+      name: package_config
193
+      url: "https://pub.flutter-io.cn"
194
+    source: hosted
195
+    version: "1.0.5"
196
+  package_resolver:
197
+    dependency: transitive
198
+    description:
199
+      name: package_resolver
200
+      url: "https://pub.flutter-io.cn"
201
+    source: hosted
202
+    version: "1.0.4"
56 203
   path:
57 204
     dependency: transitive
58 205
     description:
@@ -67,18 +214,81 @@ packages:
67 214
       url: "https://pub.flutter-io.cn"
68 215
     source: hosted
69 216
     version: "0.1.8"
217
+  plugin:
218
+    dependency: transitive
219
+    description:
220
+      name: plugin
221
+      url: "https://pub.flutter-io.cn"
222
+    source: hosted
223
+    version: "0.2.0+3"
224
+  pool:
225
+    dependency: transitive
226
+    description:
227
+      name: pool
228
+      url: "https://pub.flutter-io.cn"
229
+    source: hosted
230
+    version: "1.3.6"
231
+  pub_semver:
232
+    dependency: transitive
233
+    description:
234
+      name: pub_semver
235
+      url: "https://pub.flutter-io.cn"
236
+    source: hosted
237
+    version: "1.4.2"
70 238
   quiver:
71 239
     dependency: transitive
72 240
     description:
73 241
       name: quiver
74 242
       url: "https://pub.flutter-io.cn"
75 243
     source: hosted
76
-    version: "2.0.1"
244
+    version: "2.0.0+1"
245
+  shelf:
246
+    dependency: transitive
247
+    description:
248
+      name: shelf
249
+      url: "https://pub.flutter-io.cn"
250
+    source: hosted
251
+    version: "0.7.3+3"
252
+  shelf_packages_handler:
253
+    dependency: transitive
254
+    description:
255
+      name: shelf_packages_handler
256
+      url: "https://pub.flutter-io.cn"
257
+    source: hosted
258
+    version: "1.0.4"
259
+  shelf_static:
260
+    dependency: transitive
261
+    description:
262
+      name: shelf_static
263
+      url: "https://pub.flutter-io.cn"
264
+    source: hosted
265
+    version: "0.2.8"
266
+  shelf_web_socket:
267
+    dependency: transitive
268
+    description:
269
+      name: shelf_web_socket
270
+      url: "https://pub.flutter-io.cn"
271
+    source: hosted
272
+    version: "0.2.2+4"
77 273
   sky_engine:
78 274
     dependency: transitive
79 275
     description: flutter
80 276
     source: sdk
81 277
     version: "0.0.99"
278
+  source_map_stack_trace:
279
+    dependency: transitive
280
+    description:
281
+      name: source_map_stack_trace
282
+      url: "https://pub.flutter-io.cn"
283
+    source: hosted
284
+    version: "1.1.5"
285
+  source_maps:
286
+    dependency: transitive
287
+    description:
288
+      name: source_maps
289
+      url: "https://pub.flutter-io.cn"
290
+    source: hosted
291
+    version: "0.10.7"
82 292
   source_span:
83 293
     dependency: transitive
84 294
     description:
@@ -114,13 +324,13 @@ packages:
114 324
       url: "https://pub.flutter-io.cn"
115 325
     source: hosted
116 326
     version: "1.0.1"
117
-  test_api:
327
+  test:
118 328
     dependency: transitive
119 329
     description:
120
-      name: test_api
330
+      name: test
121 331
       url: "https://pub.flutter-io.cn"
122 332
     source: hosted
123
-    version: "0.2.1"
333
+    version: "1.3.0"
124 334
   typed_data:
125 335
     dependency: transitive
126 336
     description:
@@ -128,6 +338,13 @@ packages:
128 338
       url: "https://pub.flutter-io.cn"
129 339
     source: hosted
130 340
     version: "1.1.6"
341
+  utf:
342
+    dependency: transitive
343
+    description:
344
+      name: utf
345
+      url: "https://pub.flutter-io.cn"
346
+    source: hosted
347
+    version: "0.9.0+5"
131 348
   vector_math:
132 349
     dependency: transitive
133 350
     description:
@@ -135,5 +352,33 @@ packages:
135 352
       url: "https://pub.flutter-io.cn"
136 353
     source: hosted
137 354
     version: "2.0.8"
355
+  vm_service_client:
356
+    dependency: transitive
357
+    description:
358
+      name: vm_service_client
359
+      url: "https://pub.flutter-io.cn"
360
+    source: hosted
361
+    version: "0.2.6"
362
+  watcher:
363
+    dependency: transitive
364
+    description:
365
+      name: watcher
366
+      url: "https://pub.flutter-io.cn"
367
+    source: hosted
368
+    version: "0.9.7+10"
369
+  web_socket_channel:
370
+    dependency: transitive
371
+    description:
372
+      name: web_socket_channel
373
+      url: "https://pub.flutter-io.cn"
374
+    source: hosted
375
+    version: "1.0.9"
376
+  yaml:
377
+    dependency: transitive
378
+    description:
379
+      name: yaml
380
+      url: "https://pub.flutter-io.cn"
381
+    source: hosted
382
+    version: "2.1.15"
138 383
 sdks:
139
-  dart: ">=2.0.0 <3.0.0"
384
+  dart: ">=2.0.0-dev.68.0 <3.0.0"