Selaa lähdekoodia

预览页面的修改

Caijinglong 6 vuotta sitten
vanhempi
commit
f7c3dc4e78

+ 11
- 0
lib/src/provider/selected_provider.dart Näytä tiedosto

@@ -30,5 +30,16 @@ abstract class SelectedProvider {
30 30
     return selectedList.remove(entity);
31 31
   }
32 32
 
33
+  void compareAndRemoveEntities(List<ImageEntity> previewSelectedList) {
34
+    var srcList = List.of(selectedList);
35
+    selectedList.clear();
36
+    srcList.forEach((entity) {
37
+      if (previewSelectedList.contains(entity)){
38
+        selectedList.add(entity);
39
+      }
40
+    });
41
+  }
42
+
43
+
33 44
   void sure();
34 45
 }

+ 42
- 11
lib/src/ui/page/photo_main_page.dart Näytä tiedosto

@@ -101,7 +101,7 @@ class _PhotoMainPageState extends State<PhotoMainPage>
101 101
             options: options,
102 102
             galleryName: currentPath.name,
103 103
             onGalleryChange: _onGalleryChange,
104
-            onTapPreview: _onTapPreview,
104
+            onTapPreview: selectedList.isEmpty ? null : _onTapPreview,
105 105
             selectedProvider: this,
106 106
             galleryListProvider: this,
107 107
           ),
@@ -173,7 +173,7 @@ class _PhotoMainPageState extends State<PhotoMainPage>
173 173
   Widget _buildItem(BuildContext context, int index) {
174 174
     var data = list[index];
175 175
     return GestureDetector(
176
-      onTap: () => _onItemClick(data),
176
+      onTap: () => _onItemClick(data, index),
177 177
       child: Stack(
178 178
         children: <Widget>[
179 179
           ImageItem(
@@ -254,8 +254,6 @@ class _PhotoMainPageState extends State<PhotoMainPage>
254 254
     setState(() {});
255 255
   }
256 256
 
257
-  void _onItemClick(ImageEntity data) {}
258
-
259 257
   void _onGalleryChange(ImagePathEntity value) {
260 258
     _currentPath = value;
261 259
 
@@ -267,8 +265,33 @@ class _PhotoMainPageState extends State<PhotoMainPage>
267 265
     });
268 266
   }
269 267
 
270
-  void _onTapPreview() {
268
+  void _onItemClick(ImageEntity data, int index) {
269
+    var result = new PhotoPreviewResult();
271 270
     Navigator.of(context).push(
271
+      MaterialPageRoute(
272
+        builder: (ctx) {
273
+          return ConfigProvider(
274
+            provider: ConfigProvider.of(context).provider,
275
+            options: options,
276
+            child: PhotoPreviewPage(
277
+              selectedProvider: this,
278
+              list: List.of(list),
279
+              initIndex: index,
280
+              changeProviderOnCheckChange: true,
281
+              result: result,
282
+            ),
283
+          );
284
+        },
285
+      ),
286
+    ).then((v) {
287
+      setState(() {});
288
+    });
289
+  }
290
+
291
+  void _onTapPreview() {
292
+    var result = new PhotoPreviewResult();
293
+    Navigator.of(context)
294
+        .push(
272 295
       MaterialPageRoute(
273 296
         builder: (ctx) => ConfigProvider(
274 297
               provider: ConfigProvider.of(context).provider,
@@ -276,9 +299,16 @@ class _PhotoMainPageState extends State<PhotoMainPage>
276 299
               child: PhotoPreviewPage(
277 300
                 selectedProvider: this,
278 301
                 list: List.of(selectedList),
302
+                changeProviderOnCheckChange: false,
303
+                result: result,
279 304
               ),
280 305
             ),
281 306
       ),
307
+    )
308
+        .then(
309
+      (v) {
310
+        compareAndRemoveEntities(result.previewSelectedList);
311
+      },
282 312
     );
283 313
   }
284 314
 }
@@ -319,7 +349,7 @@ class __BottomWidgetState extends State<_BottomWidget> {
319 349
 
320 350
   @override
321 351
   Widget build(BuildContext context) {
322
-    var textStyle = TextStyle(fontSize: 14.0, color: options.textColor);
352
+    var textStyle = TextStyle(fontSize: 14.0);
323 353
     const textPadding = const EdgeInsets.symmetric(horizontal: 16.0);
324 354
     return Container(
325 355
       color: options.themeColor,
@@ -327,7 +357,7 @@ class __BottomWidgetState extends State<_BottomWidget> {
327 357
         bottom: true,
328 358
         top: false,
329 359
         child: Container(
330
-          height: 44.0,
360
+          height: 52.0,
331 361
           child: Row(
332 362
             children: <Widget>[
333 363
               GestureDetector(
@@ -339,16 +369,17 @@ class __BottomWidgetState extends State<_BottomWidget> {
339 369
                   padding: textPadding,
340 370
                   child: Text(
341 371
                     widget.galleryName,
342
-                    style: textStyle,
372
+                    style: textStyle.copyWith(color: options.textColor),
343 373
                   ),
344 374
                 ),
345 375
               ),
346 376
               Expanded(
347 377
                 child: Container(),
348 378
               ),
349
-              GestureDetector(
350
-                behavior: HitTestBehavior.translucent,
351
-                onTap: widget.onTapPreview,
379
+              FlatButton(
380
+                onPressed: widget.onTapPreview,
381
+                textColor: options.textColor,
382
+                disabledTextColor: options.disableColor,
352 383
                 child: Container(
353 384
                   height: 44.0,
354 385
                   alignment: Alignment.center,

+ 138
- 5
lib/src/ui/page/photo_preview_page.dart Näytä tiedosto

@@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
5 5
 import 'package:photo/src/entity/options.dart';
6 6
 import 'package:photo/src/provider/config_provider.dart';
7 7
 import 'package:photo/src/provider/selected_provider.dart';
8
+import 'package:photo/src/ui/page/photo_main_page.dart';
8 9
 import 'package:photo_manager/photo_manager.dart';
9 10
 
10 11
 class PhotoPreviewPage extends StatefulWidget {
@@ -12,8 +13,22 @@ class PhotoPreviewPage extends StatefulWidget {
12 13
 
13 14
   final List<ImageEntity> list;
14 15
 
15
-  const PhotoPreviewPage({Key key, this.selectedProvider, this.list})
16
-      : super(key: key);
16
+  final int initIndex;
17
+
18
+  /// 这个参数是控制在内部点击check后是否实时修改provider状态
19
+  final bool changeProviderOnCheckChange;
20
+
21
+  /// 这里封装了结果
22
+  final PhotoPreviewResult result;
23
+
24
+  const PhotoPreviewPage({
25
+    Key key,
26
+    @required this.selectedProvider,
27
+    @required this.list,
28
+    @required this.changeProviderOnCheckChange,
29
+    @required this.result,
30
+    this.initIndex = 0,
31
+  }) : super(key: key);
17 32
 
18 33
   @override
19 34
   _PhotoPreviewPageState createState() => _PhotoPreviewPageState();
@@ -28,14 +43,30 @@ class _PhotoPreviewPageState extends State<PhotoPreviewPage> {
28 43
 
29 44
   Color get textColor => options.textColor;
30 45
 
46
+  SelectedProvider get selectedProvider => widget.selectedProvider;
47
+
31 48
   List<ImageEntity> get list => widget.list;
32 49
 
33 50
   StreamController<int> pageChangeController = StreamController.broadcast();
34 51
 
52
+  Stream<int> get pageStream => pageChangeController.stream;
53
+
54
+  bool get changeProviderOnCheckChange => widget.changeProviderOnCheckChange;
55
+
56
+  List<ImageEntity> get previewSelectedList =>
57
+      widget.result.previewSelectedList;
58
+
59
+  PageController pageController;
60
+
35 61
   @override
36 62
   void initState() {
37 63
     super.initState();
38 64
     pageChangeController.add(0);
65
+    previewSelectedList.clear();
66
+    previewSelectedList.addAll(selectedProvider.selectedList);
67
+    pageController = PageController(
68
+      initialPage: widget.initIndex,
69
+    );
39 70
   }
40 71
 
41 72
   @override
@@ -52,30 +83,97 @@ class _PhotoPreviewPageState extends State<PhotoPreviewPage> {
52 83
         appBar: AppBar(
53 84
           backgroundColor: config.options.themeColor,
54 85
           title: StreamBuilder(
55
-            stream: pageChangeController.stream,
56
-            initialData: 0,
86
+            stream: pageStream,
87
+            initialData: widget.initIndex,
57 88
             builder: (ctx, snap) => Text(
58 89
                   "${snap.data + 1}/${widget.list.length}",
59 90
                 ),
60 91
           ),
61 92
         ),
62 93
         body: PageView.builder(
94
+          controller: pageController,
63 95
           itemBuilder: _buildItem,
64 96
           itemCount: list.length,
65 97
           onPageChanged: _onPageChanged,
66 98
         ),
67 99
         bottomNavigationBar: _buildBottom(),
100
+        bottomSheet: _buildThumb(),
68 101
       ),
69 102
     );
70 103
   }
71 104
 
72 105
   Widget _buildBottom() {
73 106
     return Container(
74
-      height: 44.0,
107
+      height: 52.0,
75 108
       color: themeColor,
109
+      child: Row(
110
+        children: <Widget>[
111
+          Expanded(
112
+            child: Container(),
113
+          ),
114
+          _buildCheckbox(),
115
+        ],
116
+      ),
117
+    );
118
+  }
119
+
120
+  Container _buildCheckbox() {
121
+    return Container(
122
+      constraints: BoxConstraints(
123
+        maxWidth: 150.0,
124
+      ),
125
+      child: StreamBuilder<int>(
126
+        builder: (ctx, snapshot) {
127
+          var index = snapshot.data;
128
+          var data = list[index];
129
+          return CheckboxListTile(
130
+            value: previewSelectedList.contains(data),
131
+            onChanged: (bool check) {
132
+              if (changeProviderOnCheckChange) {
133
+                _onChangeProvider(check, index);
134
+              } else {
135
+                _onCheckInOnlyPreview(check, index);
136
+              }
137
+            },
138
+            activeColor: Color.lerp(textColor, themeColor, 0.6),
139
+            title: Text(
140
+              config.provider.getSelectedOptionsText(options),
141
+              textAlign: TextAlign.end,
142
+              style: TextStyle(color: options.textColor),
143
+            ),
144
+          );
145
+        },
146
+        initialData: widget.initIndex,
147
+        stream: pageStream,
148
+      ),
76 149
     );
77 150
   }
78 151
 
152
+  /// 仅仅修改预览时的状态,在退出时,再更新provider的顺序,这里无论添加与否不修改顺序
153
+  void _onCheckInOnlyPreview(bool check, int index) {
154
+    var item = list[index];
155
+    if (check) {
156
+      previewSelectedList.add(item);
157
+    } else {
158
+      previewSelectedList.remove(item);
159
+    }
160
+    pageChangeController.add(index);
161
+  }
162
+
163
+  /// 直接修改预览状态,会直接移除item
164
+  void _onChangeProvider(bool check, int index) {
165
+    var item = list[index];
166
+    if (check) {
167
+      if (selectedProvider.addSelectEntity(item)) {
168
+        previewSelectedList.add(item);
169
+      }
170
+    } else {
171
+      selectedProvider.removeSelectEntity(item);
172
+      previewSelectedList.remove(item);
173
+    }
174
+    pageChangeController.add(index);
175
+  }
176
+
79 177
   Widget _buildItem(BuildContext context, int index) {
80 178
     var data = list[index];
81 179
     return BigPhotoImage(
@@ -86,6 +184,37 @@ class _PhotoPreviewPageState extends State<PhotoPreviewPage> {
86 184
   void _onPageChanged(int value) {
87 185
     pageChangeController.add(value);
88 186
   }
187
+
188
+  Widget _buildThumb() {
189
+    return Container(
190
+      height: 80.0,
191
+      child: ListView.builder(
192
+        itemBuilder: _buildThumbItem,
193
+        itemCount: previewSelectedList.length,
194
+        scrollDirection: Axis.horizontal,
195
+      ),
196
+    );
197
+  }
198
+
199
+  Widget _buildThumbItem(BuildContext context, int index) {
200
+    // todo 这里需要一个遮盖
201
+    var item = previewSelectedList[index];
202
+    return GestureDetector(
203
+      onTap: () => changeSelected(item, index),
204
+      child: Container(
205
+        width: 80.0,
206
+        child: ImageItem(
207
+          themeColor: themeColor,
208
+          entity: item,
209
+        ),
210
+      ),
211
+    );
212
+  }
213
+
214
+  void changeSelected(ImageEntity entity, int index) {
215
+    var itemIndex = list.indexOf(entity);
216
+    if (itemIndex != -1) pageController.jumpToPage(itemIndex);
217
+  }
89 218
 }
90 219
 
91 220
 class BigPhotoImage extends StatefulWidget {
@@ -121,3 +250,7 @@ class _BigPhotoImageState extends State<BigPhotoImage>
121 250
   @override
122 251
   bool get wantKeepAlive => true;
123 252
 }
253
+
254
+class PhotoPreviewResult {
255
+  List<ImageEntity> previewSelectedList = [];
256
+}