-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.xml
4183 lines (4135 loc) · 540 KB
/
index.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>SharkerBlog</title>
<link>https://akashark.github.io/</link>
<description>Recent content on SharkerBlog</description>
<generator>Hugo -- gohugo.io</generator>
<language>zh-cn</language>
<lastBuildDate>Tue, 25 Oct 2022 23:11:39 +0800</lastBuildDate><atom:link href="https://akashark.github.io/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>第三章基础组件 一</title>
<link>https://akashark.github.io/posts/read/flutter%E5%AE%9E%E6%88%98/%E7%AC%AC%E4%B8%89%E7%AB%A0%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6-%E4%B8%80/</link>
<pubDate>Tue, 25 Oct 2022 23:11:39 +0800</pubDate>
<guid>https://akashark.github.io/posts/read/flutter%E5%AE%9E%E6%88%98/%E7%AC%AC%E4%B8%89%E7%AB%A0%E5%9F%BA%E7%A1%80%E7%BB%84%E4%BB%B6-%E4%B8%80/</guid>
<description><p><a href="https://book.flutterchina.club/chapter3/text.html">文本及样式</a>
<a href="https://www.cnblogs.com/gloryhope/p/13367585.html">Flutter.. 两个点语法含义</a>
<a href="https://www.jianshu.com/p/35063261c583">Dart中两个点..和三个点&hellip;的用法</a></p>
<h2 id="文本及样式">文本及样式</h2>
<h3 id="常见属性">常见属性</h3>
<ul>
<li>textAlign: 文本的对齐方式;可以选择左对齐、右对齐还是居中。注意,对齐的参考系是Text widget 本身, 只有 Text 宽度大于文本内容长度时指定此属性才有意义</li>
<li>maxLines、overflow: 指定文本显示的最大行数,默认情况下,文本是自动折行的,如果指定此参数,则文本最多不会超过指定的行。如果有多余的文本,可以通过overflow来指定截断方式,默认是直接截断,本例中指定的截断方式TextOverflow.ellipsis,它会将多余文本截断后以省略符“&hellip;”表示;TextOverflow 的其他截断方式请参考 SDK 文档。</li>
<li>textScaleFactor: 代表文本相对于当前字体大小的缩放因子,相对于去设置文本的样式style属性的fontSize,它是调整字体大小的一个快捷方式。该属性的默认值可以通过MediaQueryData.textScaleFactor获得,如果没有MediaQuery,那么会默认值将为1.0。</li>
</ul>
<h3 id="textstyle">TextStyle</h3>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 4
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 5
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 6
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 7
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 8
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 9
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">10
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">11
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span>Text(<span style="color:#0ff;font-weight:bold">&#34;Hello world&#34;</span>,
</span></span><span style="display:flex;"><span> style: TextStyle(
</span></span><span style="display:flex;"><span> color: Colors.blue,
</span></span><span style="display:flex;"><span> fontSize: <span style="color:#ff0;font-weight:bold">18.0</span>,
</span></span><span style="display:flex;"><span> height: <span style="color:#ff0;font-weight:bold">1.2</span>,
</span></span><span style="display:flex;"><span> fontFamily: <span style="color:#0ff;font-weight:bold">&#34;Courier&#34;</span>,
</span></span><span style="display:flex;"><span> background: Paint()..color=Colors.yellow,
</span></span><span style="display:flex;"><span> decoration:TextDecoration.underline,
</span></span><span style="display:flex;"><span> decorationStyle: TextDecorationStyle.dashed
</span></span><span style="display:flex;"><span> ),
</span></span><span style="display:flex;"><span>);
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>height:该属性用于指定行高,但它并不是一个绝对值,而是一个因子,具体的行高等于fontSize*height。</li>
<li>fontSize:该属性和 Text 的textScaleFactor都用于控制字体大小。但是有两个主要区别:
<ul>
<li>fontSize可以精确指定字体大小,而textScaleFactor只能通过缩放比例来控制。</li>
<li>textScaleFactor主要是用于系统字体大小设置改变时对 Flutter 应用字体进行全局调整,而fontSize通常用于单个文本,字体大小不会跟随系统字体大小变化。</li>
</ul>
</li>
</ul>
<h2 id="textspan">TextSpan</h2>
<p>有点像富文本的展示方式</p>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">4
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">5
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">6
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span><span style="color:#fff;font-weight:bold">const</span> TextSpan({
</span></span><span style="display:flex;"><span> TextStyle style,
</span></span><span style="display:flex;"><span> Sting text,
</span></span><span style="display:flex;"><span> List&lt;TextSpan&gt; children,
</span></span><span style="display:flex;"><span> GestureRecognizer recognizer,
</span></span><span style="display:flex;"><span>});
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 4
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 5
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 6
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 7
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 8
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 9
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">10
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">11
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">12
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">13
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">14
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span>Text.rich(TextSpan(
</span></span><span style="display:flex;"><span> children: [
</span></span><span style="display:flex;"><span> TextSpan(
</span></span><span style="display:flex;"><span> text: <span style="color:#0ff;font-weight:bold">&#34;Home: &#34;</span>
</span></span><span style="display:flex;"><span> ),
</span></span><span style="display:flex;"><span> TextSpan(
</span></span><span style="display:flex;"><span> text: <span style="color:#0ff;font-weight:bold">&#34;https://flutterchina.club&#34;</span>,
</span></span><span style="display:flex;"><span> style: TextStyle(
</span></span><span style="display:flex;"><span> color: Colors.blue
</span></span><span style="display:flex;"><span> ),
</span></span><span style="display:flex;"><span> recognizer: _tapRecognizer
</span></span><span style="display:flex;"><span> ),
</span></span><span style="display:flex;"><span> ]
</span></span><span style="display:flex;"><span>))
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>我们通过 TextSpan 实现了一个基础文本片段和一个链接片段,然后通过Text.rich 方法将TextSpan 添加到 Text 中,之所以可以这样做,是因为 Text 其实就是 RichText 的一个包装,而RichText 是可以显示多种样式(富文本)的 widget</li>
<li></li>
</ul>
<p>ps:
在Flutter中经常会用用到..的语法糖
如下:</p>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">3
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span>state.clone()
</span></span><span style="display:flex;"><span> ..splashImg = action.img
</span></span><span style="display:flex;"><span> ..famousSentence = action.famousSentence;
</span></span></code></pre></td></tr></table>
</div>
</div><p>等价于</p>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">3
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span>state.clone()
</span></span><span style="display:flex;"><span>state.splashImg = action.img
</span></span><span style="display:flex;"><span>state.famousSentence = action.famousSentence;
</span></span></code></pre></td></tr></table>
</div>
</div><p>可以看成链式调用,但是和OC与java的链式调用不太一样
在OC/Java中链式调用有个规律,谁调用就返回谁,但是在dart中&quot;..&ldquo;不用在方法中返回调用主体,景观源码的实现方式也是通过set进去的,但是我们看到的就是Dart给我们提供的语法糖,因为Dart本身就是把成员变量的getter setter方法改成隐式的了</p>
<p>三个点(&hellip;)
是用来拼接集合 如list Map等</p>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 4
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 5
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 6
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 7
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 8
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 9
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">10
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span><span style="color:#fff;font-weight:bold">class</span> Test {
</span></span><span style="display:flex;"><span> Test() {
</span></span><span style="display:flex;"><span> <span style="color:#007f7f">//这里组合后 list就变成[ &#39;a&#39;, &#39;b&#39;, &#39;c&#39;,&#39;d&#39;, &#39;e&#39;, &#39;f&#39;]
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span> <span style="color:#fff;font-weight:bold">var</span> list2 = [<span style="color:#0ff;font-weight:bold">&#39;d&#39;</span>, <span style="color:#0ff;font-weight:bold">&#39;e&#39;</span>, <span style="color:#0ff;font-weight:bold">&#39;f&#39;</span>];
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">var</span> list = [<span style="color:#0ff;font-weight:bold">&#39;a&#39;</span>, <span style="color:#0ff;font-weight:bold">&#39;b&#39;</span>, <span style="color:#0ff;font-weight:bold">&#39;c&#39;</span>, ...list2];
</span></span><span style="display:flex;"><span> <span style="color:#007f7f">//这里组合后map就变成{&#39;a&#39;: &#39;a&#39;, &#39;b&#39;: &#39;b&#39;,&#39;c&#39;: &#39;c&#39;, &#39;d&#39;: &#39;d&#39;}
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span> <span style="color:#fff;font-weight:bold">var</span> map2 = {<span style="color:#0ff;font-weight:bold">&#39;a&#39;</span>: <span style="color:#0ff;font-weight:bold">&#39;a&#39;</span>, <span style="color:#0ff;font-weight:bold">&#39;b&#39;</span>: <span style="color:#0ff;font-weight:bold">&#39;b&#39;</span>};
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">var</span> map = {...map2, <span style="color:#0ff;font-weight:bold">&#39;c&#39;</span>: <span style="color:#0ff;font-weight:bold">&#39;c&#39;</span>, <span style="color:#0ff;font-weight:bold">&#39;d&#39;</span>: <span style="color:#0ff;font-weight:bold">&#39;d&#39;</span>};
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="defaulttextstyle">DefaultTextStyle</h2>
<p>在 Widget 树中,文本的样式默认是可以被继承的(子类文本类组件未指定具体样式时可以使用 Widget 树中父级设置的默认样式),因此,如果在 Widget 树的某一个节点处设置一个默认的文本样式,那么该节点的子树中所有文本都会默认使用这个样式,而DefaultTextStyle正是用于设置默认文本样式的
<strong>设置Widget树中子Widget的文本的样式, 如果这子Widget中设指定了对应文本样式的话(设置inherit: false, 则全部都不使用继承的默认样式),子widget的优先级会更高</strong></p>
<h2 id="字体">字体</h2>
<p>在Flutter中使用字体分两步完成,首先在pubspec.yaml中声明他们,以确保会打包到应用中,然后通过TextStyle 属性使用字体</p>
<ul>
<li>在asset中声明</li>
</ul>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 4
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 5
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 6
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 7
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 8
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 9
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">10
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">11
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">12
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="font-weight:bold">flutter</span>:
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">fonts</span>:
</span></span><span style="display:flex;"><span> - <span style="font-weight:bold">family</span>: Raleway
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">fonts</span>:
</span></span><span style="display:flex;"><span> - <span style="font-weight:bold">asset</span>: assets/fonts/Raleway-Regular.ttf
</span></span><span style="display:flex;"><span> - <span style="font-weight:bold">asset</span>: assets/fonts/Raleway-Medium.ttf
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">weight</span>: <span style="color:#ff0;font-weight:bold">500</span>
</span></span><span style="display:flex;"><span> - <span style="font-weight:bold">asset</span>: assets/fonts/Raleway-SemiBold.ttf
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">weight</span>: <span style="color:#ff0;font-weight:bold">600</span>
</span></span><span style="display:flex;"><span> - <span style="font-weight:bold">family</span>: AbrilFatface
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">fonts</span>:
</span></span><span style="display:flex;"><span> - <span style="font-weight:bold">asset</span>: assets/fonts/abrilfatface/AbrilFatface-Regular.ttf
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>使用字体</li>
</ul>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 4
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 5
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 6
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 7
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 8
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 9
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">10
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span><span style="color:#007f7f">// 声明文本样式
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span><span style="color:#fff;font-weight:bold">const</span> textStyle = <span style="color:#fff;font-weight:bold">const</span> TextStyle(
</span></span><span style="display:flex;"><span> fontFamily: <span style="color:#0ff;font-weight:bold">&#39;Raleway&#39;</span>,
</span></span><span style="display:flex;"><span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#007f7f">// 使用文本样式
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span><span style="color:#fff;font-weight:bold">var</span> buttonText = <span style="color:#fff;font-weight:bold">const</span> Text(
</span></span><span style="display:flex;"><span> <span style="color:#0ff;font-weight:bold">&#34;Use the font for this text&#34;</span>,
</span></span><span style="display:flex;"><span> style: textStyle,
</span></span><span style="display:flex;"><span>);
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>package中的字体
要使用 Package 中定义的字体,必须提供package参数。例如,假设上面的字体声明位于
my_package包中。然后创建 TextStyle 的过程如下,如果在 package 包内部使用它自己定义
的字体,也应该在创建文本样式时指定package参数</li>
</ul>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">4
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span><span style="color:#fff;font-weight:bold">const</span> textStyle = <span style="color:#fff;font-weight:bold">const</span> TextStyle(
</span></span><span style="display:flex;"><span> fontFamily: <span style="color:#0ff;font-weight:bold">&#39;Raleway&#39;</span>,
</span></span><span style="display:flex;"><span> package: <span style="color:#0ff;font-weight:bold">&#39;my_package&#39;</span>, <span style="color:#007f7f">//指定包名
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span>);
</span></span></code></pre></td></tr></table>
</div>
</div><p>一个包也可以只提供字体文件而不需要在 pubspec.yaml 中声明。 这些文件应该存放在包的lib/文件夹中。字体文件不会自动绑定到应用程序中,应用程序可以在声明字体时有选择地使用这些字体。假设一个名为my_package的包中有一个字体文件:
<code>lib/fonts/Raleway-Medium.ttf</code>
然后再声明中声明</p>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">4
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">5
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">6
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">7
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span> <span style="font-weight:bold">flutter</span>:
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">fonts</span>:
</span></span><span style="display:flex;"><span> - <span style="font-weight:bold">family</span>: Raleway
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">fonts</span>:
</span></span><span style="display:flex;"><span> - <span style="font-weight:bold">asset</span>: assets/fonts/Raleway-Regular.ttf
</span></span><span style="display:flex;"><span> - <span style="font-weight:bold">asset</span>: packages/my_package/fonts/Raleway-Medium.ttf
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">weight</span>: <span style="color:#ff0;font-weight:bold">500</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>ps: lib/是隐含的,所以它不应该包含在 asset 路径中。</p>
<p>在这种情况下,由于应用程序本地定义了字体,所以在创建TextStyle时可以不指定package参数:</p>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">3
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span><span style="color:#fff;font-weight:bold">const</span> textStyle = <span style="color:#fff;font-weight:bold">const</span> TextStyle(
</span></span><span style="display:flex;"><span> fontFamily: <span style="color:#0ff;font-weight:bold">&#39;Raleway&#39;</span>,
</span></span><span style="display:flex;"><span>);
</span></span></code></pre></td></tr></table>
</div>
</div></description>
</item>
<item>
<title>第一个Flutter应用 四</title>
<link>https://akashark.github.io/posts/read/flutter%E5%AE%9E%E6%88%98/%E7%AC%AC%E4%B8%80%E4%B8%AAflutter%E5%BA%94%E7%94%A8-%E5%9B%9B/</link>
<pubDate>Sun, 09 Oct 2022 10:35:30 +0800</pubDate>
<guid>https://akashark.github.io/posts/read/flutter%E5%AE%9E%E6%88%98/%E7%AC%AC%E4%B8%80%E4%B8%AAflutter%E5%BA%94%E7%94%A8-%E5%9B%9B/</guid>
<description><p><a href="https://book.flutterchina.club/chapter2/first_flutter_app.html#_2-1-1-%E5%88%9B%E5%BB%BAflutter%E5%BA%94%E7%94%A8%E6%A8%A1%E6%9D%BF">第二章</a></p>
<h2 id="调试flutter应用">调试Flutter应用</h2>
<h3 id="日志与断点">日志与断点</h3>
<h4 id="debugger-声明">debugger() 声明</h4>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">4
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span><span style="color:#fff;font-weight:bold">void</span> someFunction(<span style="color:#fff;font-weight:bold">double</span> offset) {
</span></span><span style="display:flex;"><span> debugger(when: offset &gt; <span style="color:#ff0;font-weight:bold">30.0</span>);
</span></span><span style="display:flex;"><span> <span style="color:#007f7f">// ...
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span>}
</span></span></code></pre></td></tr></table>
</div>
</div><h4 id="printdebugprintflutter-logs">print、debugPrint、flutter logs</h4>
<p>Dart print()功能将输出到系统控制台,我们可以使用flutter logs来查看它(基本上是一个包装adb logcat)。</p>
<p>如果你一次输出太多,那么Android有时会丢弃一些日志行。为了避免这种情况,我们可以使用Flutter的foundation库中的debugPrint() (opens new window)。 这是一个封装print,它将输出限制在一个级别,避免被Android内核丢弃。</p>
<p>Flutter框架中的许多类都有toString实现。按照惯例,这些输出通常包括对象的runtimeType单行输出,通常在表单中ClassName(more information about this instance…)。 树中使用的一些类也具有toStringDeep,从该点返回整个子树的多行描述。已一些具有详细信息toString的类会实现一个toStringShort,它只返回对象的类型或其他非常简短的(一个或两个单词)描述。</p>
<h4 id="调试模式断言">调试模式断言</h4>
<p>在Flutter应用调试过程中,Dart assert语句被启用,并且 Flutter 框架使用它来执行许多运行时检查来验证是否违反一些不可变的规则。当一个某个规则被违反时,就会在控制台打印错误日志,并带上一些上下文信息来帮助追踪问题的根源。</p>
<p>要关闭调试模式并使用发布模式,请使用flutter run &ndash;release运行我们的应用程序。 这也关闭了Observatory调试器。一个中间模式可以关闭除Observatory之外所有调试辅助工具的,称为“profile mode”,用&ndash;profile替代&ndash;release即可。</p>
<h4 id="断点">断点</h4>
<p>Vscode 或者 AS上自带的</p>
<h3 id="调试应用程序层">调试应用程序层</h3>
<p>widget树 渲染树 Layer树
文档写的太少了而且没有实操,这个地方再找找资料补充下
官网上有对于DevTools的相关教程
<a href="https://docs.flutter.dev/development/tools/devtools/overview">教程</a></p>
<h2 id="异常捕获">异常捕获</h2>
<h3 id="dart单线程模型">Dart单线程模型</h3>
<p><img loading="lazy" src="http://media.wjbbf.cn/mweb/16652812113231.jpg" alt="" />
Dart线程运行过程,如上图中所示,入口函数 main() 执行完后,消息循环机制便启动了。首先会按照先进先出的顺序逐个执行微任务队列中的任务,事件任务执行完毕后程序便会退出,但是,在事件任务执行的过程中也可以插入新的微任务和事件任务,在这种情况下,整个线程的执行过程便是一直在循环,不会退出,而Flutter中,主线程的执行过程正是如此,永不终止。
在Dart中,所有的外部事件任务都在事件队列中,如IO、计时器、点击、以及绘制事件等,而微任务通常来源于Dart内部,并且微任务非常少,之所以如此,是因为微任务队列优先级高,如果微任务太多,执行时间总和就越久,事件队列任务的延迟也就越久,对于GUI应用来说最直观的表现就是比较卡,所以必须得保证微任务队列不会太长。值得注意的是,我们可以通过Future.microtask(…)方法向微任务队列插入一个任务。
在事件循环中,当某个任务发生异常并没有被捕获时,程序并不会退出,而直接导致的结果是当前任务的后续代码就不会被执行了,也就是说一个任务中的异常是不会影响其他任务执行的。</p>
<h3 id="flutter框架异常捕获">Flutter框架异常捕获</h3>
<p>onError是FlutterError的一个静态属性,它有一个默认的处理方法 dumpErrorToConsole,到这里就清晰了,如果我们想自己上报异常,只需要提供一个自定义的错误处理回调即可,如:</p>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">4
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">5
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">6
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span><span style="color:#fff;font-weight:bold">void</span> main() {
</span></span><span style="display:flex;"><span> FlutterError.onError = (FlutterErrorDetails details) {
</span></span><span style="display:flex;"><span> reportError(details);
</span></span><span style="display:flex;"><span> };
</span></span><span style="display:flex;"><span> ...
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>这样我们就可以处理那些Flutter为我们捕获的异常了</p>
<h3 id="其他异常捕获与日志收集">其他异常捕获与日志收集</h3>
<p>在Flutter中,还有一些Flutter没有为我们捕获的异常,如调用空对象方法异常、Future中的异常。在Dart中,异常分两类:同步异常和异步异常,同步异常可以通过try/catch捕获,而异步异常则比较麻烦,如下面的代码是捕获不了Future的异常的:</p>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">4
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">5
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span><span style="color:#fff;font-weight:bold">try</span>{
</span></span><span style="display:flex;"><span> Future.delayed(Duration(seconds: <span style="color:#ff0;font-weight:bold">1</span>)).then((e) =&gt; Future.error(<span style="color:#0ff;font-weight:bold">&#34;xxx&#34;</span>));
</span></span><span style="display:flex;"><span>}<span style="color:#fff;font-weight:bold">catch</span> (e){
</span></span><span style="display:flex;"><span> print(e)
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><p>Dart中有一个runZoned(&hellip;) 方法,可以给执行对象指定一个Zone。Zone表示一个代码执行的环境范围,为了方便理解,读者可以将Zone类比为一个代码执行沙箱,不同沙箱的之间是隔离的,沙箱可以捕获、拦截或修改一些代码行为,如Zone中可以捕获日志输出、Timer创建、微任务调度的行为,同时Zone也可以捕获所有未处理的异常。下面我们看看runZoned(&hellip;)方法定义:</p>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">4
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span>R runZoned&lt;R&gt;(R body(), {
</span></span><span style="display:flex;"><span> Map zoneValues,
</span></span><span style="display:flex;"><span> ZoneSpecification zoneSpecification,
</span></span><span style="display:flex;"><span>})
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>zoneValues: Zone 的私有数据,可以通过实例zone[key]获取,可以理解为每个“沙箱”的私有数据。</li>
<li>zoneSpecification:Zone的一些配置,可以自定义一些代码行为,比如拦截日志输出和错误等,举个例子:</li>
</ul>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 4
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 5
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 6
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 7
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 8
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 9
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">10
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">11
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">12
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">13
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">14
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span>runZoned(
</span></span><span style="display:flex;"><span> () =&gt; runApp(MyApp()),
</span></span><span style="display:flex;"><span> zoneSpecification: ZoneSpecification(
</span></span><span style="display:flex;"><span> <span style="color:#007f7f">// 拦截print 蜀西湖
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span> print: (Zone self, ZoneDelegate parent, Zone zone, <span style="color:#fff;font-weight:bold">String</span> line) {
</span></span><span style="display:flex;"><span> parent.print(zone, <span style="color:#0ff;font-weight:bold">&#34;Interceptor: </span><span style="color:#0ff;font-weight:bold">$</span>line<span style="color:#0ff;font-weight:bold">&#34;</span>);
</span></span><span style="display:flex;"><span> },
</span></span><span style="display:flex;"><span> <span style="color:#007f7f">// 拦截未处理的异步错误
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span> handleUncaughtError: (Zone self, ZoneDelegate parent, Zone zone,
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">Object</span> error, StackTrace stackTrace) {
</span></span><span style="display:flex;"><span> parent.print(zone, <span style="color:#0ff;font-weight:bold">&#39;</span><span style="color:#0ff;font-weight:bold">${</span>error.toString()<span style="color:#0ff;font-weight:bold">}</span><span style="color:#0ff;font-weight:bold"> </span><span style="color:#0ff;font-weight:bold">$</span>stackTrace<span style="color:#0ff;font-weight:bold">&#39;</span>);
</span></span><span style="display:flex;"><span> },
</span></span><span style="display:flex;"><span> ),
</span></span><span style="display:flex;"><span>);
</span></span></code></pre></td></tr></table>
</div>
</div><p>这样一来,我们 APP 中所有调用print方法输出日志的行为都会被拦截,通过这种方式,我们也可以在应用中记录日志,等到应用触发未捕获的异常时,将异常信息和日志统一上报。
另外我们还拦截了未被捕获的异步错误,这样一来,结合上面的 FlutterError.onError 我们就可以捕获我们Flutter应用错误了并进行上报了!如下</p>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 4
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 5
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 6
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 7
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 8
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 9
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">10
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">11
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">12
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">13
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">14
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">15
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">16
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">17
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">18
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">19
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">20
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">21
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">22
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">23
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">24
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">25
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">26
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">27
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">28
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">29
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">30
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">31
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">32
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">33
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">34
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">35
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span><span style="color:#fff;font-weight:bold">void</span> collectLog(<span style="color:#fff;font-weight:bold">String</span> line){
</span></span><span style="display:flex;"><span> ... <span style="color:#007f7f">//收集日志
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span>}
</span></span><span style="display:flex;"><span><span style="color:#fff;font-weight:bold">void</span> reportErrorAndLog(FlutterErrorDetails details){
</span></span><span style="display:flex;"><span> ... <span style="color:#007f7f">//上报错误和日志逻辑
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>FlutterErrorDetails makeDetails(<span style="color:#fff;font-weight:bold">Object</span> obj, StackTrace stack){
</span></span><span style="display:flex;"><span> ...<span style="color:#007f7f">// 构建错误信息
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#fff;font-weight:bold">void</span> main() {
</span></span><span style="display:flex;"><span><span style="color:#007f7f">// 已经捕获的异常
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span> <span style="color:#fff;font-weight:bold">var</span> onError = FlutterError.onError; <span style="color:#007f7f">//先将 onerror 保存起来
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span> FlutterError.onError = (FlutterErrorDetails details) {
</span></span><span style="display:flex;"><span> onError?.call(details); <span style="color:#007f7f">//调用默认的onError
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span> reportErrorAndLog(details); <span style="color:#007f7f">//上报
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span> };
</span></span><span style="display:flex;"><span> runZoned(
</span></span><span style="display:flex;"><span> () =&gt; runApp(MyApp()),
</span></span><span style="display:flex;"><span> zoneSpecification: ZoneSpecification(
</span></span><span style="display:flex;"><span> <span style="color:#007f7f">// 拦截print
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span> print: (Zone self, ZoneDelegate parent, Zone zone, <span style="color:#fff;font-weight:bold">String</span> line) {
</span></span><span style="display:flex;"><span> collectLog(line);
</span></span><span style="display:flex;"><span> parent.print(zone, <span style="color:#0ff;font-weight:bold">&#34;Interceptor: </span><span style="color:#0ff;font-weight:bold">$</span>line<span style="color:#0ff;font-weight:bold">&#34;</span>);
</span></span><span style="display:flex;"><span> },
</span></span><span style="display:flex;"><span> <span style="color:#007f7f">// 拦截未处理的异步错误
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span> handleUncaughtError: (Zone self, ZoneDelegate parent, Zone zone,
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">Object</span> error, StackTrace stackTrace) {
</span></span><span style="display:flex;"><span> reportErrorAndLog(details);
</span></span><span style="display:flex;"><span> parent.print(zone, <span style="color:#0ff;font-weight:bold">&#39;</span><span style="color:#0ff;font-weight:bold">${</span>error.toString()<span style="color:#0ff;font-weight:bold">}</span><span style="color:#0ff;font-weight:bold"> </span><span style="color:#0ff;font-weight:bold">$</span>stackTrace<span style="color:#0ff;font-weight:bold">&#39;</span>);
</span></span><span style="display:flex;"><span> },
</span></span><span style="display:flex;"><span> ),
</span></span><span style="display:flex;"><span> );
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div></description>
</item>
<item>
<title>第一个Flutter应用 三</title>
<link>https://akashark.github.io/posts/read/flutter%E5%AE%9E%E6%88%98/%E7%AC%AC%E4%B8%80%E4%B8%AAflutter%E5%BA%94%E7%94%A8-%E4%B8%89/</link>
<pubDate>Fri, 07 Oct 2022 23:36:30 +0800</pubDate>
<guid>https://akashark.github.io/posts/read/flutter%E5%AE%9E%E6%88%98/%E7%AC%AC%E4%B8%80%E4%B8%AAflutter%E5%BA%94%E7%94%A8-%E4%B8%89/</guid>
<description><p><a href="https://book.flutterchina.club/chapter2/first_flutter_app.html#_2-1-1-%E5%88%9B%E5%BB%BAflutter%E5%BA%94%E7%94%A8%E6%A8%A1%E6%9D%BF">第二章</a></p>
<h2 id="路由管理">路由管理</h2>
<h3 id="materialpageroute">MaterialPageRoute</h3>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">4
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">5
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">6
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">7
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span><span style="color:#007f7f">// 路由跳转
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span> Navigator.push(
</span></span><span style="display:flex;"><span> context,
</span></span><span style="display:flex;"><span> MaterialPageRoute(builder: (context){
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">return</span> <span style="color:#fff;font-weight:bold">const</span> NewRoute();
</span></span><span style="display:flex;"><span> })
</span></span><span style="display:flex;"><span> );
</span></span></code></pre></td></tr></table>
</div>
</div><p>MaterialPageRoute继承自PageRoute类,PageRoute类是一个抽象类,表示占有整个屏幕空间的一个模态路由页面,它还定义了路由构建及切换时过渡动画的相关接口及属性。MaterialPageRoute 是 Material组件库提供的组件,它可以针对不同平台,实现与平台页面切换动画风格一致的路由切换动画</p>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">4
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">5
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">6
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span> MaterialPageRoute({
</span></span><span style="display:flex;"><span> WidgetBuilder builder,
</span></span><span style="display:flex;"><span> RouteSettings settings,
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">bool</span> maintainState = <span style="color:#fff;font-weight:bold">true</span>,
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">bool</span> fullscreenDialog = <span style="color:#fff;font-weight:bold">false</span>,
</span></span><span style="display:flex;"><span> })
</span></span></code></pre></td></tr></table>
</div>
</div><p>MaterialPageRoute构造函数 (可以点进去看注释,注释写的也很清楚)</p>
<ul>
<li>builder 是一个WidgetBuilder类型的回调函数,它的作用是构建路由页面的具体内容,返回值是一个widget。我们通常要实现此回调,返回新路由的实例。</li>
<li>settings 包含路由的配置信息,如路由名称、是否初始路由(首页)。</li>
<li>maintainState:默认情况下,当入栈一个新路由时,原来的路由仍然会被保存在内存中,如果想在路由没用的时候释放其所占用的所有资源,可以设置maintainState为 false。</li>
<li>fullscreenDialog表示新的路由页面是否是一个全屏的模态对话框,在 iOS 中,如果fullscreenDialog为true,新页面将会从屏幕底部滑入(而不是水平方向)。</li>
</ul>
<h3 id="navigator">Navigator</h3>
<p>Navigator是一个路由管理的组件,它提供了打开和退出路由页方法。Navigator通过一个栈来管理活动路由集合。通常当前屏幕显示的页面就是栈顶的路由。
常用方法</p>
<ul>
<li>Future push(BuildContext context, Route route)
将给定的路由入栈(即打开新的页面),返回值是一个Future对象,用以接收新路由出栈(即关闭)时的
返回数据。</li>
<li>bool pop(BuildContext context, [ result ])
将栈顶路由出栈,result 为页面关闭时返回给上一个页面的数据。</li>
<li>实例方法
Navigator类第一个参数为context的静态方法都对应一个Navigator的实例方法,比如
Navigator.push(BuildContext context, Route route)等价于
Navigator.of(context).push(Route route) ,下面命名路由相关的方法也是一样的。</li>
</ul>
<p>Navigator 还有很多其他方法,如Navigator.replace、Navigator.popUntil等,详情请参考
API文档或SDK 源码注释,在此不再赘述。</p>
<h3 id="路由传值非命名路由">路由传值(非命名路由)</h3>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 4
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 5
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 6
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 7
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 8
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 9
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">10
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">11
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">12
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">13
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">14
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">15
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">16
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">17
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">18
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">19
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">20
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">21
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">22
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">23
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">24
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">25
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">26
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">27
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">28
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">29
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">30
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">31
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">32
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">33
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">34
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">35
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">36
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">37
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">38
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">39
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">40
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">41
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">42
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">43
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">44
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">45
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">46
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">47
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">48
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">49
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">50
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">51
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">52
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">53
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">54
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">55
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">56
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">57
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span><span style="color:#fff;font-weight:bold">class</span> TipRoute <span style="color:#fff;font-weight:bold">extends</span> StatelessWidget {
</span></span><span style="display:flex;"><span> TipRoute({
</span></span><span style="display:flex;"><span> Key key,
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">required</span> <span style="color:#fff;font-weight:bold">this</span>.text, <span style="color:#007f7f">// 接收一个text参数
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span> }) : <span style="color:#fff;font-weight:bold">super</span>(key: key);
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">final</span> <span style="color:#fff;font-weight:bold">String</span> text;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#f00">@</span>override
</span></span><span style="display:flex;"><span> Widget build(BuildContext context) {
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">return</span> Scaffold(
</span></span><span style="display:flex;"><span> appBar: AppBar(
</span></span><span style="display:flex;"><span> title: Text(<span style="color:#0ff;font-weight:bold">&#34;提示&#34;</span>),
</span></span><span style="display:flex;"><span> ),
</span></span><span style="display:flex;"><span> body: Padding(
</span></span><span style="display:flex;"><span> padding: EdgeInsets.all(<span style="color:#ff0;font-weight:bold">18</span>),
</span></span><span style="display:flex;"><span> child: Center(
</span></span><span style="display:flex;"><span> child: Column(
</span></span><span style="display:flex;"><span> children: &lt;Widget&gt;[
</span></span><span style="display:flex;"><span> Text(text),
</span></span><span style="display:flex;"><span> ElevatedButton(
</span></span><span style="display:flex;"><span> onPressed: () =&gt; Navigator.pop(context, <span style="color:#0ff;font-weight:bold">&#34;我是返回值&#34;</span>),
</span></span><span style="display:flex;"><span> child: Text(<span style="color:#0ff;font-weight:bold">&#34;返回&#34;</span>),
</span></span><span style="display:flex;"><span> )
</span></span><span style="display:flex;"><span> ],
</span></span><span style="display:flex;"><span> ),
</span></span><span style="display:flex;"><span> ),
</span></span><span style="display:flex;"><span> ),
</span></span><span style="display:flex;"><span> );
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#fff;font-weight:bold">class</span> RouterTestRoute <span style="color:#fff;font-weight:bold">extends</span> StatelessWidget {
</span></span><span style="display:flex;"><span> <span style="color:#f00">@</span>override
</span></span><span style="display:flex;"><span> Widget build(BuildContext context) {
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">return</span> Center(
</span></span><span style="display:flex;"><span> child: ElevatedButton(
</span></span><span style="display:flex;"><span> onPressed: () <span style="color:#fff;font-weight:bold">async</span> {
</span></span><span style="display:flex;"><span> <span style="color:#007f7f">// 打开`TipRoute`,并等待返回结果
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span> <span style="color:#fff;font-weight:bold">var</span> result = <span style="color:#fff;font-weight:bold">await</span> Navigator.push(
</span></span><span style="display:flex;"><span> context,
</span></span><span style="display:flex;"><span> MaterialPageRoute(
</span></span><span style="display:flex;"><span> builder: (context) {
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">return</span> TipRoute(
</span></span><span style="display:flex;"><span> <span style="color:#007f7f">// 路由参数
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span> text: <span style="color:#0ff;font-weight:bold">&#34;我是提示xxxx&#34;</span>,
</span></span><span style="display:flex;"><span> );
</span></span><span style="display:flex;"><span> },
</span></span><span style="display:flex;"><span> ),
</span></span><span style="display:flex;"><span> );
</span></span><span style="display:flex;"><span> <span style="color:#007f7f">//输出`TipRoute`路由返回结果
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span> print(<span style="color:#0ff;font-weight:bold">&#34;路由返回值: </span><span style="color:#0ff;font-weight:bold">$</span>result<span style="color:#0ff;font-weight:bold">&#34;</span>);
</span></span><span style="display:flex;"><span> },
</span></span><span style="display:flex;"><span> child: Text(<span style="color:#0ff;font-weight:bold">&#34;打开提示页&#34;</span>),
</span></span><span style="display:flex;"><span> ),
</span></span><span style="display:flex;"><span> );
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="命名路由">命名路由</h3>
<p>所谓命名路由,即有名字的路由,我们可以先给路由起一个名字,然后就可以通过路由名字直接打开新路由了,这为路由管理带来了一种直观、简单的方式。</p>
<h4 id="路由表">路由表</h4>
<p><code>Map&lt;String, WidgetBuilder&gt; routes;</code>他是一个Map,key为路由的名字,是一个字符串,value是个builder回调函数,用于生成相应的路由widget。</p>
<p>注册路由表</p>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 4
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 5
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 6
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 7
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 8
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 9
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">10
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">11
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">12
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span>MaterialApp(
</span></span><span style="display:flex;"><span> title: <span style="color:#0ff;font-weight:bold">&#39;Flutter Demo&#39;</span>,
</span></span><span style="display:flex;"><span> initialRoute:<span style="color:#0ff;font-weight:bold">&#34;/&#34;</span>, <span style="color:#007f7f">//名为&#34;/&#34;的路由作为应用的home(首页)
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span> theme: ThemeData(
</span></span><span style="display:flex;"><span> primarySwatch: Colors.blue,
</span></span><span style="display:flex;"><span> ),
</span></span><span style="display:flex;"><span> <span style="color:#007f7f">//注册路由表
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span> routes:{
</span></span><span style="display:flex;"><span> <span style="color:#0ff;font-weight:bold">&#34;new_page&#34;</span>:(context) =&gt; NewRoute(),
</span></span><span style="display:flex;"><span> <span style="color:#0ff;font-weight:bold">&#34;/&#34;</span>:(context) =&gt; MyHomePage(title: <span style="color:#0ff;font-weight:bold">&#39;Flutter Demo Home Page&#39;</span>), <span style="color:#007f7f">//注册首页路由
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span> }
</span></span><span style="display:flex;"><span>);
</span></span></code></pre></td></tr></table>
</div>
</div><p>跳转要通过路由名称来打开新路由,可以使用Navigator 的pushNamed方法:
<code>Future pushNamed(BuildContext context, String routeName,{Object arguments})</code></p>
<h4 id="传递参数">传递参数</h4>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 4
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 5
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 6
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 7
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 8
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 9
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">10
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">11
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span><span style="color:#fff;font-weight:bold">class</span> EchoRoute <span style="color:#fff;font-weight:bold">extends</span> StatelessWidget {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span> <span style="color:#f00">@</span>override
</span></span><span style="display:flex;"><span> Widget build(BuildContext context) {
</span></span><span style="display:flex;"><span> <span style="color:#007f7f">//获取路由参数
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span> <span style="color:#fff;font-weight:bold">var</span> args=ModalRoute.of(context).settings.arguments;
</span></span><span style="display:flex;"><span> <span style="color:#007f7f">//...省略无关代码
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span> }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Navigator.of(context).pushNamed(<span style="color:#0ff;font-weight:bold">&#34;new_page&#34;</span>, arguments: <span style="color:#0ff;font-weight:bold">&#34;hi&#34;</span>);
</span></span></code></pre></td></tr></table>
</div>
</div><p>对于有构造函数,并且构造函数需要传递参数的Widget我们可以使用下面的方式进行适配</p>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">4
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">5
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">6
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">7
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">8
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span>MaterialApp(
</span></span><span style="display:flex;"><span> ... <span style="color:#007f7f">//省略无关代码
</span></span></span><span style="display:flex;"><span><span style="color:#007f7f"></span> routes: {
</span></span><span style="display:flex;"><span> <span style="color:#0ff;font-weight:bold">&#34;tip2&#34;</span>: (context){
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">return</span> TipRoute(text: ModalRoute.of(context)!.settings.arguments);
</span></span><span style="display:flex;"><span> },
</span></span><span style="display:flex;"><span> },
</span></span><span style="display:flex;"><span>);
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="路由生成钩子">路由生成钩子</h3>
<p>MaterialApp有一个onGenerateRoute属性,它在打开命名路由时可能会被调用,之所以说可能,是因为当调用Navigator.pushNamed(&hellip;)打开命名路由时,如果指定的路由名在路由表中已注册,则会调用路由表中的builder函数来生成路由组件;如果路由表中没有注册,才会调用onGenerateRoute来生成路由。onGenerateRoute回调签名如下:
<code>Route&lt;dynamic&gt; Function(RouteSettings settings)</code></p>
<p>有了onGenerateRoute回调,要实现上面控制页面权限的功能就非常容易:我们放弃使用路由表,取而代之的是提供一个onGenerateRoute回调,然后在该回调中进行统一的权限控制,如:</p>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 4
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 5
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 6
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 7
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 8
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 9
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">10
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">11
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">12
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">13
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span> onGenerateRoute: (settings) {
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">return</span> MaterialPageRoute(builder: (context) {
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">String</span>? routeName = settings.name;
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">switch</span> (routeName) {
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">case</span> <span style="color:#0ff;font-weight:bold">&#34;/&#34;</span>: {
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">return</span> MyHomePage(title: <span style="color:#0ff;font-weight:bold">&#34;title&#34;</span>);
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">case</span> <span style="color:#0ff;font-weight:bold">&#34;new&#34;</span>: {
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">return</span> NewRoute(titleStr: <span style="color:#0ff;font-weight:bold">&#34;titleStr&#34;</span>);
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">return</span> Scaffold();
</span></span><span style="display:flex;"><span> });
</span></span></code></pre></td></tr></table>
</div>
</div><p>其中MaterialPageRoute</p>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 4
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 5
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 6
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 7
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 8
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 9
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">10
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-dart" data-lang="dart"><span style="display:flex;"><span> MaterialPageRoute({
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">required</span> <span style="color:#fff;font-weight:bold">this</span>.builder,
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">super</span>.settings,
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">this</span>.maintainState = <span style="color:#fff;font-weight:bold">true</span>,
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">super</span>.fullscreenDialog,
</span></span><span style="display:flex;"><span> }) : <span style="color:#fff;font-weight:bold">assert</span>(builder != <span style="color:#fff;font-weight:bold">null</span>),
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">assert</span>(maintainState != <span style="color:#fff;font-weight:bold">null</span>),
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">assert</span>(fullscreenDialog != <span style="color:#fff;font-weight:bold">null</span>) {
</span></span><span style="display:flex;"><span> <span style="color:#fff;font-weight:bold">assert</span>(opaque);
</span></span><span style="display:flex;"><span> }
</span></span></code></pre></td></tr></table>
</div>
</div><p>传入widgetBuild返回一个Route的子类</p>
<h2 id="总结">总结</h2>
<p>建议使用命名路由的形式,这将会带来如下好处:</p>
<ul>
<li>语义化更明确。</li>
<li>代码更好维护;如果使用匿名路由,则必须在调用Navigator.push的地方创建新路由页,这样不仅需要import新路由页的dart文件,而且这样的代码将会非常分散。</li>
<li>可以通过onGenerateRoute做一些全局的路由跳转前置处理逻辑。</li>
</ul>
<h2 id="包管理">包管理</h2>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 4
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 5
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 6
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 7
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 8
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272"> 9
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">10
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">11
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">12
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">13
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">14
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">15
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">16
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="font-weight:bold">name</span>: flutter_in_action
</span></span><span style="display:flex;"><span><span style="font-weight:bold">description</span>: First Flutter Application.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="font-weight:bold">version</span>: <span style="color:#ff0;font-weight:bold">1.0.0+1</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="font-weight:bold">dependencies</span>:
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">flutter</span>:
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">sdk</span>: flutter
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">cupertino_icons</span>: ^0.1.2
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="font-weight:bold">dev_dependencies</span>:
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">flutter_test</span>:
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">sdk</span>: flutter
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="font-weight:bold">flutter</span>:
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">uses-material-design</span>: <span style="color:#fff;font-weight:bold">true</span>
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>name: 应用或者包名</li>
<li>description: 应用或包的描述、简介。</li>
<li>version:应用或包的版本号。</li>
<li>dependencies:应用或包依赖的其他包或插件。</li>
<li>dev_dependencies:开发环境依赖的工具包(而不是flutter应用本身依赖的包)。</li>
<li>flutter:flutter相关的配置选项。</li>
</ul>
<p>如果我们的Flutter应用本身依赖某个包,我们需要将所依赖的包添加到dependencies下就可以了</p>
<h3 id="pub仓库">Pub仓库</h3>
<p>Pub(https://pub.dev/ )是 Google 官方的 Dart Packages 仓库,类似于 node 中的 npm仓库、Android中的 jcenter。我们可以在 Pub 上面查找我们需要的包和插件,也可以向 Pub 发布我们的包和插件。我们将在后面的章节中介绍如何向 Pub 发布我们的包和插件。</p>
<p>我们可以使用IDE的功能或者手动运行flutter packages get 命令来下载依赖包。另外,需要注意dependencies和dev_dependencies的区别,前者的依赖包将作为App的源码的一部分参与编译,生成最终的安装包。而后者的依赖包只是作为开发阶段的一些工具包,主要是用于帮助我们提高开发、测试效率,比如 flutter 的自动化测试包等。</p>
<h4 id="本地依赖">本地依赖</h4>
<p>如果我们正在本地开发一个包,包名为pkg1,我们可以通过下面方式依赖:</p>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">3
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="font-weight:bold">dependencies</span>:
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">pkg1</span>:
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">path</span>: ../../code/pkg1
</span></span></code></pre></td></tr></table>
</div>
</div><h4 id="git依赖">git依赖</h4>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">4
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="font-weight:bold">dependencies</span>:
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">pkg1</span>:
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">git</span>:
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">url</span>: git://github.com/xxx/pkg1.git
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">4
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">5
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="font-weight:bold">dependencies</span>:
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">package1</span>:
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">git</span>:
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">url</span>: git://github.com/flutter/packages.git
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">path</span>: packages/package1
</span></span></code></pre></td></tr></table>
</div>
</div><p>问题他们这个不应该也有一个对于包的描述文件么,比如podspec之类的</p>
<h2 id="资源管理">资源管理</h2>
<h3 id="指定-assets">指定 assets</h3>
<div class="highlight"><div style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">
<table style="border-spacing:0;padding:0;margin:0;border:0;"><tr><td style="vertical-align:top;padding:0;margin:0;border:0;">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">1
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">2
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">3
</span><span style="white-space:pre;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#727272">4
</span></code></pre></td>
<td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%">
<pre tabindex="0" style="color:#e5e5e5;background-color:#000;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="font-weight:bold">flutter</span>:
</span></span><span style="display:flex;"><span> <span style="font-weight:bold">assets</span>:
</span></span><span style="display:flex;"><span> - assets/my_icon.png
</span></span><span style="display:flex;"><span> - assets/background.png
</span></span></code></pre></td></tr></table>
</div>
</div><p>assets指定应包含在应用程序中的文件, 每个 asset 都通过相对于pubspec.yaml文件所在的文件系统路径来标识自身的路径。asset 的声明顺序是无关紧要的,asset的实际目录可以是任意文件夹(在本示例中是assets 文件夹)</p>
<h3 id="加载文本assets">加载文本assets</h3>
<ul>
<li>通过rootBundle (opens new window)对象加载:每个Flutter应用程序都有一个rootBundle (opens new window)对象, 通过它可以轻松访问主资源包,直接使用package:flutter/services.dart中全局静态的rootBundle对象来加载asset即可。</li>
<li>通过 DefaultAssetBundle (opens new window)加载:建议使用 DefaultAssetBundle (opens new window)来获取当前 BuildContext 的AssetBundle。 这种方法不是使用应用程序构建的默认 asset bundle,而是使父级 widget 在运行时动态替换的不同的 AssetBundle,这对于本地化或测试场景很有用。</li>
</ul>
<p>通常,可以使用DefaultAssetBundle.of()在应用运行时来间接加载 asset(例如JSON文件),而在widget 上下文之外,或其他AssetBundle句柄不可用时,可以使用rootBundle直接加载这些 asset,例如:</p>
<h3 id="加载图片">加载图片</h3>
<p>主资源默认对应于1.0倍的分辨率图片。看一个例子:</p>
<ul>
<li>…/my_icon.png</li>