Browse Source

fix image

lucky1213 4 years ago
parent
commit
3b9ae8a3f5

+ 8
- 0
packages/zefyr/example/lib/src/images.dart View File

@@ -3,7 +3,9 @@
3 3
 // BSD-style license that can be found in the LICENSE file.
4 4
 
5 5
 import 'dart:io';
6
+import 'dart:typed_data';
6 7
 
8
+import 'package:flutter/material.dart';
7 9
 import 'package:flutter/widgets.dart';
8 10
 import 'package:image_picker/image_picker.dart';
9 11
 import 'package:zefyr/zefyr.dart';
@@ -37,4 +39,10 @@ class CustomImageDelegate implements ZefyrImageDelegate<ImageSource> {
37 39
       return Image(image: image);
38 40
     }
39 41
   }
42
+
43
+  @override
44
+  Future<String> picked(asset) async {
45
+    File file = await asset.file;
46
+    return file.uri.toString();
47
+  }
40 48
 }

+ 96
- 57
packages/zefyr/lib/src/widgets/buttons.dart View File

@@ -1,8 +1,8 @@
1 1
 // Copyright (c) 2018, the Zefyr project authors.  Please see the AUTHORS file
2 2
 // for details. All rights reserved. Use of this source code is governed by a
3 3
 // BSD-style license that can be found in the LICENSE file.
4
+import 'dart:async';
4 5
 import 'dart:io';
5
-import 'dart:typed_data';
6 6
 
7 7
 import 'package:flutter/material.dart';
8 8
 import 'package:flutter/services.dart';
@@ -437,6 +437,9 @@ class ImageButton extends StatefulWidget {
437 437
 }
438 438
 
439 439
 class _ImageButtonState extends State<ImageButton> {
440
+
441
+  List<AssetEntity> pickedAssetList = [];
442
+
440 443
   @override
441 444
   Widget build(BuildContext context) {
442 445
     final toolbar = ZefyrToolbar.of(context);
@@ -464,6 +467,7 @@ class _ImageButtonState extends State<ImageButton> {
464 467
   Widget buildOverlay(BuildContext context) {
465 468
     final theme = ZefyrTheme.of(context).toolbarTheme;
466 469
     final toolbar = ZefyrToolbar.of(context);
470
+    final pickedChangeController = StreamController<List<AssetEntity>>.broadcast();
467 471
     return Material(
468 472
       color: theme.color,
469 473
       child: Container(
@@ -527,8 +531,17 @@ class _ImageButtonState extends State<ImageButton> {
527 531
                                     sortDelegate: SortDelegate.common,
528 532
                                     pickType: PickType.onlyImage,
529 533
                                     photoPathList: null,
530
-                                  ).then((List<AssetEntity> imgList) {
531
-                                    
534
+                                  ).then((List<AssetEntity> entity) async {
535
+                                    if (entity.isNotEmpty) {
536
+                                      toolbar.closeOverlay();
537
+                                      final editor = ZefyrToolbar.of(context).editor;
538
+                                      for (var asset in entity) {
539
+                                        final image = await editor.imageDelegate.picked(asset);
540
+                                        if (image != null) {
541
+                                          editor.formatSelection(NotusAttribute.embed.image(image));
542
+                                        }
543
+                                      }
544
+                                    }
532 545
                                   });
533 546
                                 },
534 547
                                 child: Container(
@@ -565,15 +578,25 @@ class _ImageButtonState extends State<ImageButton> {
565 578
                           toolbar.editor.tapHandle = TapHandle.previewImage;
566 579
                         },
567 580
                         child: PhotoPicker.buildGallery(
568
-                          context: context,
569
-                          padding: 4,
570
-                          thumbSize: 300,
571
-                          itemRadio: 0.5,
572
-                          provider: I18nProvider.chinese,
573
-                          sortDelegate: SortDelegate.common,
574
-                          pickType: PickType.onlyImage,
575
-                          photoPathList: null,
576
-                        ),
581
+                              context: context,
582
+                              padding: 4,
583
+                              thumbSize: 300,
584
+                              itemRadio: 0.5,
585
+                              provider: I18nProvider.chinese,
586
+                              sortDelegate: SortDelegate.common,
587
+                              pickType: PickType.onlyImage,
588
+                              photoPathList: null,
589
+                              onSelected: (List<AssetEntity> entity) {
590
+                                pickedChangeController.add(entity);
591
+                              }
592
+                            ),
593
+                        // StreamBuilder<List<AssetEntity>>(
594
+                        //   stream: pickedChangeController.stream,
595
+                        //   initialData: [],
596
+                        //   builder: (context, snapshot) {
597
+                        //     return 
598
+                        //   },
599
+                        // ),
577 600
                       ),
578 601
                     ),
579 602
                   ],
@@ -584,52 +607,67 @@ class _ImageButtonState extends State<ImageButton> {
584 607
               height: 50,
585 608
               color: theme.color,
586 609
               padding: EdgeInsets.symmetric(horizontal: 20),
587
-              child: Row(
588
-                children: [
589
-                  Expanded(
590
-                    child: Row(
591
-                      children: [
592
-                        SizedBox(
593
-                          width: 16,
594
-                          height: 16,
595
-                          child: Radio<bool>(
596
-                            value: false,
597
-                            groupValue: false,
598
-                            onChanged: (bool result) {},
599
-                          ),
610
+              child: StreamBuilder(
611
+                builder: (context, snapshot) {
612
+                  return Row(
613
+                    children: [
614
+                      Expanded(
615
+                        child: Row(
616
+                          children: [
617
+                            SizedBox(
618
+                              width: 16,
619
+                              height: 16,
620
+                              child: Radio<bool>(
621
+                                value: false,
622
+                                groupValue: false,
623
+                                onChanged: (bool result) {},
624
+                              ),
625
+                            ),
626
+                            Padding(
627
+                              padding: EdgeInsets.symmetric(horizontal: 8),
628
+                              child: Text(
629
+                                '原图',
630
+                                style: TextStyle(color: theme.iconColor, fontSize: 16),
631
+                              ),
632
+                            ),
633
+                          ],
600 634
                         ),
601
-                        Padding(
602
-                          padding: EdgeInsets.symmetric(horizontal: 8),
635
+                      ),
636
+                      FlatButton(
637
+                        padding: EdgeInsets.zero,
638
+                        color: theme.toggleColor,
639
+                        disabledColor: theme.disabledIconColor,
640
+                        shape: StadiumBorder(),
641
+                        onPressed: snapshot.data.isNotEmpty ? () async {
642
+                          pickedChangeController.add([]);
643
+                          toolbar.closeOverlay();
644
+                          for (var asset in snapshot.data) {
645
+                            final image = await toolbar.editor.imageDelegate.picked(asset);
646
+                            if (image != null) {
647
+                              toolbar.editor.formatSelection(NotusAttribute.embed.image(image));
648
+                            }
649
+                          }
650
+                        } : null,
651
+                        child: Container(
652
+                          height: 30,
653
+                          alignment: Alignment.center,
654
+                          padding: EdgeInsets.symmetric(horizontal: 20),
603 655
                           child: Text(
604
-                            '原图',
605
-                            style:
606
-                                TextStyle(color: theme.iconColor, fontSize: 16),
656
+                              '上传 (${snapshot.data.length})',
657
+                              style: TextStyle(
658
+                                color: Colors.white,
659
+                                fontSize: 14,
660
+                              ),
661
+                            ),
607 662
                           ),
608 663
                         ),
609
-                      ],
610
-                    ),
611
-                  ),
612
-                  FlatButton(
613
-                    padding: EdgeInsets.zero,
614
-                    color: theme.toggleColor,
615
-                    shape: StadiumBorder(),
616
-                    onPressed: () {},
617
-                    child: Container(
618
-                      height: 30,
619
-                      alignment: Alignment.center,
620
-                      padding: EdgeInsets.symmetric(horizontal: 20),
621
-                      child: Text(
622
-                        '上传 (2)',
623
-                        style: TextStyle(
624
-                          color: Colors.white,
625
-                          fontSize: 14,
626
-                        ),
627
-                      ),
628
-                    ),
629
-                  ),
630
-                ],
664
+                    ],
665
+                  );
666
+                },
667
+                initialData: [],
668
+                stream: pickedChangeController.stream,
631 669
               ),
632
-            )
670
+            ),
633 671
           ],
634 672
         ),
635 673
       ),
@@ -647,10 +685,11 @@ class _ImageButtonState extends State<ImageButton> {
647 685
 
648 686
   void _pickFromGallery() async {
649 687
     final editor = ZefyrToolbar.of(context).editor;
650
-    final image = await editor.imageDelegate
651
-        .pickImage(editor.imageDelegate.gallerySource);
652
-    if (image != null) {
653
-      editor.formatSelection(NotusAttribute.embed.image(image));
688
+    for (var asset in pickedAssetList) {
689
+      final image = await editor.imageDelegate.picked(asset);
690
+      if (image != null) {
691
+        editor.formatSelection(NotusAttribute.embed.image(image));
692
+      }
654 693
     }
655 694
   }
656 695
 }

+ 5
- 5
packages/zefyr/lib/src/widgets/editable_text.dart View File

@@ -118,7 +118,7 @@ class _ZefyrEditableTextState extends State<ZefyrEditableText>
118 118
     final scope = ZefyrScope.of(context);
119 119
     if (_focusNode.hasFocus) {
120 120
       // var show = scope.overlayBuilder == null ? true : false;
121
-      _input.openConnection(widget.controller.plainTextEditingValue, widget.keyboardAppearance, show: _focusNode.consumeKeyboardToken());
121
+      _input.openConnection(widget.controller.plainTextEditingValue, widget.keyboardAppearance, showKeyboard: _focusNode.consumeKeyboardToken());
122 122
     } else {
123 123
       FocusScope.of(context).requestFocus(_focusNode);
124 124
     }
@@ -308,14 +308,14 @@ class _ZefyrEditableTextState extends State<ZefyrEditableText>
308 308
 
309 309
   void _handleFocusChange() {
310 310
     final scope = ZefyrScope.of(context);
311
-    var show = true;
311
+    var showKeyboard = true;
312 312
     if (_focusNode.consumeKeyboardToken()) {
313
-      show = scope.tapHandle == null;
313
+      showKeyboard = scope.tapHandle == null;
314 314
     } else {
315
-      show = false;
315
+      showKeyboard = false;
316 316
     }
317 317
     _input.openOrCloseConnection(_focusNode,
318
-        widget.controller.plainTextEditingValue, widget.keyboardAppearance, show: show);
318
+        widget.controller.plainTextEditingValue, widget.keyboardAppearance, showKeyboard: showKeyboard);
319 319
     _cursorTimer.startOrStop(_focusNode, selection);
320 320
     updateKeepAlive();
321 321
   }

+ 4
- 1
packages/zefyr/lib/src/widgets/image.dart View File

@@ -10,6 +10,7 @@ import 'package:flutter/widgets.dart';
10 10
 import 'package:meta/meta.dart';
11 11
 import 'package:notus/notus.dart';
12 12
 import 'package:zefyr/zefyr.dart';
13
+import 'package:photo_manager/photo_manager.dart';
13 14
 
14 15
 import 'editable_box.dart';
15 16
 
@@ -38,6 +39,8 @@ abstract class ZefyrImageDelegate<S> {
38 39
   /// an image file on user's device, an HTTP link, or an identifier generated
39 40
   /// by a file hosting service like AWS S3 or Google Drive.
40 41
   Future<String> pickImage(S source);
42
+
43
+  Future<String> picked(AssetEntity list);
41 44
 }
42 45
 
43 46
 class ZefyrImage extends StatefulWidget {
@@ -220,7 +223,7 @@ class RenderEditableImage extends RenderBox
220 223
         minWidth: 0.0,
221 224
         maxWidth: width,
222 225
         minHeight: 0.0,
223
-        maxHeight: (width * 9 / 16).floorToDouble(),
226
+        //maxHeight: (width * 9 / 16).floorToDouble(),
224 227
       );
225 228
       child.layout(childConstraints, parentUsesSize: true);
226 229
       _lastChildSize = child.size;

+ 4
- 4
packages/zefyr/lib/src/widgets/input.dart View File

@@ -25,16 +25,16 @@ class InputConnectionController implements TextInputClient {
25 25
   /// Opens or closes input connection based on the current state of
26 26
   /// [focusNode] and [value].
27 27
   void openOrCloseConnection(FocusNode focusNode, TextEditingValue value,
28
-      Brightness keyboardAppearance, {bool show = true}) {
28
+      Brightness keyboardAppearance, {bool showKeyboard = true}) {
29 29
         //  && focusNode.consumeKeyboardToken()
30 30
     if (focusNode.hasFocus) {
31
-      openConnection(value, keyboardAppearance, show: show);
31
+      openConnection(value, keyboardAppearance, showKeyboard: showKeyboard);
32 32
     } else if (!focusNode.hasFocus) {
33 33
       closeConnection();
34 34
     }
35 35
   }
36 36
 
37
-  void openConnection(TextEditingValue value, Brightness keyboardAppearance, {bool show = true}) {
37
+  void openConnection(TextEditingValue value, Brightness keyboardAppearance, {bool showKeyboard = true}) {
38 38
     if (!hasConnection) {
39 39
       _lastKnownRemoteTextEditingValue = value;
40 40
       _textInputConnection = TextInput.attach(
@@ -50,7 +50,7 @@ class InputConnectionController implements TextInputClient {
50 50
       )..setEditingState(value);
51 51
       _sentRemoteValues.add(value);
52 52
     }
53
-    if (show) {
53
+    if (showKeyboard) {
54 54
       _textInputConnection.show();
55 55
     }
56 56
   }

+ 1
- 1
packages/zefyr/lib/src/widgets/toolbar.dart View File

@@ -310,7 +310,7 @@ class ZefyrToolbarState extends State<ZefyrToolbar>
310 310
     } else {
311 311
       layers.add(
312 312
         Container(
313
-          height: keyboardHeight ?? 300,
313
+          height: keyboardHeight,
314 314
         ),
315 315
       );
316 316
     }

+ 5
- 0
packages/zefyr/test/widgets/buttons_test.dart View File

@@ -199,4 +199,9 @@ class _TestImageDelegate implements ZefyrImageDelegate<String> {
199 199
   Future<String> pickImage(String source) {
200 200
     return Future.value("file:///tmp/test.jpg");
201 201
   }
202
+
203
+  @override
204
+  Future<String> picked(list) async {
205
+    return Future.value("file:///tmp/test.jpg");
206
+  }
202 207
 }

+ 5
- 0
packages/zefyr/test/widgets/image_test.dart View File

@@ -103,4 +103,9 @@ class _TestImageDelegate implements ZefyrImageDelegate<String> {
103 103
   Future<String> pickImage(String source) {
104 104
     return Future.value("file:///tmp/test.jpg");
105 105
   }
106
+
107
+  @override
108
+  Future<String> picked(asset) async {
109
+    return Future.value("file:///tmp/test.jpg");
110
+  }
106 111
 }

+ 5
- 0
packages/zefyr/test/widgets/scope_test.dart View File

@@ -90,4 +90,9 @@ class _TestImageDelegate implements ZefyrImageDelegate<String> {
90 90
   Future<String> pickImage(String source) {
91 91
     return null;
92 92
   }
93
+
94
+  @override
95
+  Future<String> picked(asset) async {
96
+    return null;
97
+  }
93 98
 }