-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
1122 lines (784 loc) · 206 KB
/
index.html
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
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
<link rel="mask-icon" href="/images/logo.svg" color="#222">
<link rel="stylesheet" href="/css/main.css">
<link rel="stylesheet" href="/lib/font-awesome/css/all.min.css">
<script id="hexo-configurations">
var NexT = window.NexT || {};
var CONFIG = {"hostname":"example.com","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":false,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
</script>
<meta name="description" content="别走那么快,这样会错过沿途的风景的!">
<meta property="og:type" content="website">
<meta property="og:title" content="Damon-Blog">
<meta property="og:url" content="http://example.com/index.html">
<meta property="og:site_name" content="Damon-Blog">
<meta property="og:description" content="别走那么快,这样会错过沿途的风景的!">
<meta property="og:locale" content="zh_CN">
<meta property="article:author" content="Damon">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="http://example.com/">
<script id="page-configurations">
// https://hexo.io/docs/variables.html
CONFIG.page = {
sidebar: "",
isHome : true,
isPost : false,
lang : 'zh-CN'
};
</script>
<title>Damon-Blog</title>
<noscript>
<style>
.use-motion .brand,
.use-motion .menu-item,
.sidebar-inner,
.use-motion .post-block,
.use-motion .pagination,
.use-motion .comments,
.use-motion .post-header,
.use-motion .post-body,
.use-motion .collection-header { opacity: initial; }
.use-motion .site-title,
.use-motion .site-subtitle {
opacity: initial;
top: initial;
}
.use-motion .logo-line-before i { left: initial; }
.use-motion .logo-line-after i { right: initial; }
</style>
</noscript>
</head>
<body itemscope itemtype="http://schema.org/WebPage">
<div class="container use-motion">
<div class="headband"></div>
<header class="header" itemscope itemtype="http://schema.org/WPHeader">
<div class="header-inner"><div class="site-brand-container">
<div class="site-nav-toggle">
<div class="toggle" aria-label="切换导航栏">
<span class="toggle-line toggle-line-first"></span>
<span class="toggle-line toggle-line-middle"></span>
<span class="toggle-line toggle-line-last"></span>
</div>
</div>
<div class="site-meta">
<a href="/" class="brand" rel="start">
<span class="logo-line-before"><i></i></span>
<h1 class="site-title">Damon-Blog</h1>
<span class="logo-line-after"><i></i></span>
</a>
</div>
<div class="site-nav-right">
<div class="toggle popup-trigger">
</div>
</div>
</div>
<nav class="site-nav">
<ul id="menu" class="main-menu menu">
<li class="menu-item menu-item-home">
<a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a>
</li>
<li class="menu-item menu-item-about">
<a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于</a>
</li>
<li class="menu-item menu-item-tags">
<a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a>
</li>
<li class="menu-item menu-item-categories">
<a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a>
</li>
<li class="menu-item menu-item-archives">
<a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a>
</li>
</ul>
</nav>
</div>
</header>
<div class="back-to-top">
<i class="fa fa-arrow-up"></i>
<span>0%</span>
</div>
<main class="main">
<div class="main-inner">
<div class="content-wrap">
<div class="content index posts-expand">
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="http://example.com/2021/06/19/Android/Android%E5%B8%B8%E7%94%A8%E7%9F%A5%E8%AF%86%E7%82%B9/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.jpeg">
<meta itemprop="name" content="Damon">
<meta itemprop="description" content="别走那么快,这样会错过沿途的风景的!">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Damon-Blog">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2021/06/19/Android/Android%E5%B8%B8%E7%94%A8%E7%9F%A5%E8%AF%86%E7%82%B9/" class="post-title-link" itemprop="url">Android-常用知识点</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2021-06-19 16:24:08" itemprop="dateCreated datePublished" datetime="2021-06-19T16:24:08+08:00">2021-06-19</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">更新于</span>
<time title="修改时间:2021-06-21 14:04:14" itemprop="dateModified" datetime="2021-06-21T14:04:14+08:00">2021-06-21</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/Android/" itemprop="url" rel="index"><span itemprop="name">Android</span></a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h1 id="一:权限相关"><a href="#一:权限相关" class="headerlink" title="一:权限相关"></a>一:权限相关</h1><h2 id="1,检测是否获取到权限:"><a href="#1,检测是否获取到权限:" class="headerlink" title="1,检测是否获取到权限:"></a>1,检测是否获取到权限:</h2><ul>
<li><p><code>ContextCompat.checkSelfPermission(this, permission)</code></p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">```返回的结果 == PackageManager.PERMISSION_DENIED```,即被用户拒绝</span><br><span class="line"></span><br><span class="line">```kotlin</span><br><span class="line">val permissionCheck = ContextCompat.checkSelfPermission(this, permission)</span><br><span class="line">if (permissionCheck == PackageManager.PERMISSION_GRANTED) {</span><br><span class="line"> Log.d("权限", "请求成功 = ${permissionCheck}")</span><br><span class="line">}else{</span><br><span class="line"> Log.d("权限", "请求失败 = ${permissionCheck}")</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li>
</ul>
<h2 id="2,请求权限"><a href="#2,请求权限" class="headerlink" title="2,请求权限"></a>2,请求权限</h2><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 请求权限</span></span><br><span class="line">ActivityCompat.requestPermissions(<span class="keyword">this</span>, deniedPermissions, <span class="number">121</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 请求的结果</span></span><br><span class="line"><span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onRequestPermissionsResult</span><span class="params">(</span></span></span><br><span class="line"><span class="params"><span class="function"> requestCode: <span class="type">Int</span>,</span></span></span><br><span class="line"><span class="params"><span class="function"> permissions: <span class="type">Array</span><<span class="type">out</span> <span class="type">String</span>>,</span></span></span><br><span class="line"><span class="params"><span class="function"> grantResults: <span class="type">IntArray</span></span></span></span><br><span class="line"><span class="params"><span class="function">)</span></span> {</span><br><span class="line"> </span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 结果</span></span><br><span class="line"><span class="comment">// permissions = [android.permission.ACCESS_FINE_LOCATION, android.permission.WRITE_EXTERNAL_STORAGE, android.permission.ACCESS_COARSE_LOCATION]</span></span><br><span class="line"><span class="comment">// grantResults = [-1, -1, -1]</span></span><br></pre></td></tr></table></figure>
<h2 id="3,用户拒绝权限"><a href="#3,用户拒绝权限" class="headerlink" title="3,用户拒绝权限"></a>3,用户拒绝权限</h2><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 用户首次请求权限,此方法返回false,表示第一次请求,不用做什么操作</span></span><br><span class="line"><span class="comment">// 用户首次请求权限的时候拒绝了,第二次请求的时候,此方法返回true,表示之前你拒绝了,那么我要提醒你为什么我需要这个权限</span></span><br><span class="line"><span class="comment">// 用户第二次请求还拒绝了,并点击不再提醒,此方法返回false,表示我提醒你了,不过你还是执意,那我就不管你了</span></span><br><span class="line">ActivityCompat.shouldShowRequestPermissionRationale(<span class="keyword">this</span>, deniedPermission)</span><br></pre></td></tr></table></figure>
<h2 id="4,跳转到系统页面"><a href="#4,跳转到系统页面" class="headerlink" title="4,跳转到系统页面"></a>4,跳转到系统页面</h2><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 跳转到系统界面</span></span><br><span class="line"><span class="keyword">val</span> intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)</span><br><span class="line"><span class="keyword">val</span> uri = Uri.fromParts(<span class="string">"package"</span>, getPackageName(), <span class="literal">null</span>)</span><br><span class="line">intent.setData(uri)</span><br><span class="line">startActivityForResult(intent, <span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 监听,再次判断是否给予了权限</span></span><br><span class="line"><span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onActivityReenter</span><span class="params">(resultCode: <span class="type">Int</span>, <span class="keyword">data</span>: <span class="type">Intent</span>?)</span></span> {</span><br><span class="line"> <span class="keyword">if</span> (requestCode == <span class="number">1</span>) {</span><br><span class="line"> </span><br><span class="line"> } </span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="5,关于地理位置"><a href="#5,关于地理位置" class="headerlink" title="5,关于地理位置"></a>5,关于地理位置</h2><p>在使用蓝牙扫描,WIFI扫描的时候需要授予位置权限,并打开位置信息</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// ====== 第一种方式</span></span><br><span class="line"><span class="comment">// 判断位置信息是否开启</span></span><br><span class="line"><span class="keyword">val</span> lm = getSystemService(Context.LOCATION_SERVICE) <span class="keyword">as</span> LocationManager</span><br><span class="line"><span class="comment">// 使用GPS定位</span></span><br><span class="line"><span class="keyword">val</span> gps_enable = lm.isProviderEnabled(LocationManager.GPS_PROVIDER)</span><br><span class="line"><span class="comment">// 使用网络定位</span></span><br><span class="line"><span class="keyword">val</span> net_enable = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)</span><br><span class="line"></span><br><span class="line"><span class="comment">// ====== 第二种方式</span></span><br><span class="line"><span class="comment">// 判断位置信息是否打开</span></span><br><span class="line"><span class="keyword">if</span> (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {</span><br><span class="line"> <span class="keyword">var</span> locationMode = Settings.Secure.LOCATION_MODE_OFF</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> locationMode = Settings.Secure.getInt(</span><br><span class="line"> <span class="keyword">this</span>.contentResolver,</span><br><span class="line"> Settings.Secure.LOCATION_MODE</span><br><span class="line"> )</span><br><span class="line"> } <span class="keyword">catch</span> (e: SettingNotFoundException) {</span><br><span class="line"> <span class="comment">// do nothing</span></span><br><span class="line"> }</span><br><span class="line"> Log.d(GPS_TAG, <span class="string">"locationMode != Settings.Secure.LOCATION_MODE_OFF = <span class="subst">${locationMode != Settings.Secure.LOCATION_MODE_OFF}</span>"</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h1 id="二:使用相关"><a href="#二:使用相关" class="headerlink" title="二:使用相关"></a>二:使用相关</h1><h2 id="Android(P及以上)无法使用Http协议"><a href="#Android(P及以上)无法使用Http协议" class="headerlink" title="Android(P及以上)无法使用Http协议"></a>Android(P及以上)无法使用Http协议</h2><p>解决方法:</p>
<p>1,在res目录下新建一个xml目录,放入一个xml文件</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><?xml version="1.0" encoding="utf-8"?></span></span><br><span class="line"><span class="tag"><<span class="name">network-security-config</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">base-config</span> <span class="attr">cleartextTrafficPermitted</span>=<span class="string">"true"</span> /></span></span><br><span class="line"><span class="tag"></<span class="name">network-security-config</span>></span></span><br></pre></td></tr></table></figure>
<p>2,在AndroidManifest.xml使用</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><?xml version="1.0" encoding="utf-8"?></span></span><br><span class="line"><span class="tag"><<span class="name">manifest</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">application</span></span></span><br><span class="line"><span class="tag"> <span class="attr">...</span> </span></span><br><span class="line"><span class="tag"> <span class="attr">android:networkSecurityConfig</span>=<span class="string">"@xml/network_security_config"</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">application</span>></span></span><br><span class="line"><span class="tag"></<span class="name">manifest</span>></span></span><br></pre></td></tr></table></figure>
<h2 id="Android-Dialog显示"><a href="#Android-Dialog显示" class="headerlink" title="Android Dialog显示"></a>Android Dialog显示</h2><p>xml样式解析</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"> <span class="tag"><<span class="name">style</span> <span class="attr">name</span>=<span class="string">"AlertDialogStyleLoading"</span> <span class="attr">parent</span>=<span class="string">"@android:style/Theme.Dialog"</span>></span><span class="xml"></span></span><br><span class="line"><span class="xml"> <span class="tag"><<span class="name">item</span> <span class="attr">name</span>=<span class="string">"android:windowBackground"</span>></span>@android:color/transparent<span class="tag"></<span class="name">item</span>></span></span></span><br><span class="line"><span class="xml"> <span class="tag"><<span class="name">item</span> <span class="attr">name</span>=<span class="string">"android:windowContentOverlay"</span>></span>@null<span class="tag"></<span class="name">item</span>></span></span></span><br><span class="line"><span class="xml"> <span class="tag"><<span class="name">item</span> <span class="attr">name</span>=<span class="string">"android:windowIsFloating"</span>></span>true<span class="tag"></<span class="name">item</span>></span></span></span><br><span class="line"><span class="xml"> <span class="tag"><<span class="name">item</span> <span class="attr">name</span>=<span class="string">"android:windowFrame"</span>></span>@null<span class="tag"></<span class="name">item</span>></span></span></span><br><span class="line"><span class="xml"> <span class="tag"><<span class="name">item</span> <span class="attr">name</span>=<span class="string">"android:backgroundDimEnabled"</span>></span>false<span class="tag"></<span class="name">item</span>></span></span></span><br><span class="line"><span class="xml"> <span class="tag"><<span class="name">item</span> <span class="attr">name</span>=<span class="string">"android:windowNoTitle"</span>></span>true<span class="tag"></<span class="name">item</span>></span></span></span><br><span class="line"><span class="xml"> <span class="tag"><<span class="name">item</span> <span class="attr">name</span>=<span class="string">"android:windowIsTranslucent"</span>></span>true<span class="tag"></<span class="name">item</span>></span></span></span><br><span class="line"><span class="xml"></span><span class="tag"></<span class="name">style</span>></span></span><br></pre></td></tr></table></figure>
<ul>
<li>windowBackground:背景颜色</li>
<li>windowContentOverlay : 是否有遮盖</li>
<li>windowIsFloating:是否悬浮在Activity上</li>
<li>windowFrame:是否有边框</li>
<li>backgroundDimEnabled: 是否对话框背景变暗</li>
<li>windowNoTitle: 是否有标题</li>
<li>windowIsTranslucent:是否透明</li>
</ul>
<h2 id="EditText一些限制"><a href="#EditText一些限制" class="headerlink" title="EditText一些限制"></a>EditText一些限制</h2><ul>
<li><p>禁止输入空格</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 添加过滤器</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">EditTextSpaceFilter</span>: <span class="type">InputFilter {</span></span></span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">filter</span><span class="params">(</span></span></span><br><span class="line"><span class="params"><span class="function"> source: <span class="type">CharSequence</span>?,</span></span></span><br><span class="line"><span class="params"><span class="function"> start: <span class="type">Int</span>,</span></span></span><br><span class="line"><span class="params"><span class="function"> end: <span class="type">Int</span>,</span></span></span><br><span class="line"><span class="params"><span class="function"> dest: <span class="type">Spanned</span>?,</span></span></span><br><span class="line"><span class="params"><span class="function"> dstart: <span class="type">Int</span>,</span></span></span><br><span class="line"><span class="params"><span class="function"> dend: <span class="type">Int</span></span></span></span><br><span class="line"><span class="params"><span class="function"> )</span></span>: CharSequence? {</span><br><span class="line"> <span class="keyword">if</span> (source.isNullOrEmpty()) {</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">null</span></span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//返回null表示接收输入的字符,返回空字符串表示不接受输入的字符</span></span><br><span class="line"> <span class="keyword">if</span> (Character.isWhitespace(source.first()))</span><br><span class="line"> <span class="keyword">return</span> <span class="string">""</span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">null</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 添加</span></span><br><span class="line">et_wifi_password.filters = arrayOf(</span><br><span class="line"> EditTextSpaceFilter(), <span class="comment">// 空格过滤器</span></span><br><span class="line"> InputFilter.LengthFilter(<span class="number">10</span>) <span class="comment">// 长度过滤器</span></span><br><span class="line">)</span><br></pre></td></tr></table></figure></li>
<li><p>禁止复制粘贴</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 禁止输入框复制粘贴菜单</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@SuppressLint(<span class="meta-string">"ClickableViewAccessibility"</span>)</span></span><br><span class="line"><span class="keyword">open</span> <span class="function"><span class="keyword">fun</span> <span class="title">disableCopyAndPaste</span><span class="params">(editText: <span class="type">EditText</span>?)</span></span> {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">if</span> (editText == <span class="literal">null</span>) {</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> }</span><br><span class="line"> editText.setOnLongClickListener(View.OnLongClickListener { <span class="literal">true</span> })</span><br><span class="line"> editText.isLongClickable = <span class="literal">false</span></span><br><span class="line"> editText.setOnTouchListener(View.OnTouchListener { v, event -></span><br><span class="line"> <span class="keyword">if</span> (event.action === MotionEvent.ACTION_DOWN) {</span><br><span class="line"> <span class="comment">// setInsertionDisabled when user touches the view</span></span><br><span class="line"> setInsertionDisabled(editText)</span><br><span class="line"> }</span><br><span class="line"> <span class="literal">false</span></span><br><span class="line"> })</span><br><span class="line"> editText.customSelectionActionModeCallback = <span class="keyword">object</span> : ActionMode.Callback {</span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onCreateActionMode</span><span class="params">(mode: <span class="type">ActionMode</span>?, menu: <span class="type">Menu</span>?)</span></span>: <span class="built_in">Boolean</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onPrepareActionMode</span><span class="params">(mode: <span class="type">ActionMode</span>?, menu: <span class="type">Menu</span>?)</span></span>: <span class="built_in">Boolean</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onActionItemClicked</span><span class="params">(mode: <span class="type">ActionMode</span>?, item: <span class="type">MenuItem</span>?)</span></span>: <span class="built_in">Boolean</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onDestroyActionMode</span><span class="params">(mode: <span class="type">ActionMode</span>?)</span></span> {}</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">catch</span> (e: Exception) {</span><br><span class="line"> e.printStackTrace()</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li>
</ul>
<h2 id="Activity页面设置"><a href="#Activity页面设置" class="headerlink" title="Activity页面设置"></a>Activity页面设置</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//无title</span></span><br><span class="line">requestWindowFeature(Window.FEATURE_NO_TITLE);</span><br><span class="line"><span class="comment">//全屏</span></span><br><span class="line">getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,</span><br><span class="line">WindowManager.LayoutParams.FLAG_FULLSCREEN);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 坚持竖屏</span></span><br><span class="line">setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);</span><br></pre></td></tr></table></figure>
<h1 id="三:使用相关"><a href="#三:使用相关" class="headerlink" title="三:使用相关"></a>三:使用相关</h1><h2 id="1,正则验证"><a href="#1,正则验证" class="headerlink" title="1,正则验证"></a>1,正则验证</h2><ul>
<li><p>IP地址</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">([1-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])(\.(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])){3}</span><br></pre></td></tr></table></figure></li>
</ul>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="http://example.com/2021/06/19/Android/Kotlin/Kotlin-%E5%8D%8F%E7%A8%8B/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.jpeg">
<meta itemprop="name" content="Damon">
<meta itemprop="description" content="别走那么快,这样会错过沿途的风景的!">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Damon-Blog">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2021/06/19/Android/Kotlin/Kotlin-%E5%8D%8F%E7%A8%8B/" class="post-title-link" itemprop="url">Kotlin-协程</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2021-06-19 16:24:08" itemprop="dateCreated datePublished" datetime="2021-06-19T16:24:08+08:00">2021-06-19</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">更新于</span>
<time title="修改时间:2021-06-21 14:03:16" itemprop="dateModified" datetime="2021-06-21T14:03:16+08:00">2021-06-21</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/Android-Kotlin/" itemprop="url" rel="index"><span itemprop="name">Android Kotlin</span></a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="http://example.com/2021/06/19/Android/%E9%9D%A2%E8%AF%95/Android%E9%9D%A2%E8%AF%95/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.jpeg">
<meta itemprop="name" content="Damon">
<meta itemprop="description" content="别走那么快,这样会错过沿途的风景的!">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Damon-Blog">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2021/06/19/Android/%E9%9D%A2%E8%AF%95/Android%E9%9D%A2%E8%AF%95/" class="post-title-link" itemprop="url">Android-面试</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2021-06-19 16:24:08" itemprop="dateCreated datePublished" datetime="2021-06-19T16:24:08+08:00">2021-06-19</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">更新于</span>
<time title="修改时间:2021-06-21 14:04:02" itemprop="dateModified" datetime="2021-06-21T14:04:02+08:00">2021-06-21</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/Android/" itemprop="url" rel="index"><span itemprop="name">Android</span></a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h1 id="面试一"><a href="#面试一" class="headerlink" title="面试一"></a>面试一</h1><h2 id="页面-A-页面-B的跳转过程方法的调用"><a href="#页面-A-页面-B的跳转过程方法的调用" class="headerlink" title="页面 A - 页面 B的跳转过程方法的调用"></a>页面 A - 页面 B的跳转过程方法的调用</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">启动A页面:</span></span><br><span class="line"><span class="comment"> A - onCreate()</span></span><br><span class="line"><span class="comment"> A - onStart()</span></span><br><span class="line"><span class="comment"> A - onResume()</span></span><br><span class="line"><span class="comment">跳转到B页面:</span></span><br><span class="line"><span class="comment"> A - onPause()</span></span><br><span class="line"><span class="comment"> B - onCreate()</span></span><br><span class="line"><span class="comment"> B - onStart()</span></span><br><span class="line"><span class="comment"> B - onResume()</span></span><br><span class="line"><span class="comment"> A - onStop()</span></span><br><span class="line"><span class="comment">B页面返回到A页面:</span></span><br><span class="line"><span class="comment"> B - onPause()</span></span><br><span class="line"><span class="comment"> A - onRestart()</span></span><br><span class="line"><span class="comment"> A - onStart()</span></span><br><span class="line"><span class="comment"> A - onResume()</span></span><br><span class="line"><span class="comment"> B - onStop()</span></span><br><span class="line"><span class="comment"> B - onDestroy()</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>
<h2 id="Service的启动方式"><a href="#Service的启动方式" class="headerlink" title="Service的启动方式"></a>Service的启动方式</h2><h2 id="Http使用"><a href="#Http使用" class="headerlink" title="Http使用"></a>Http使用</h2><h2 id="设计模式"><a href="#设计模式" class="headerlink" title="设计模式"></a>设计模式</h2><h2 id="MVC,MVP,MVVM"><a href="#MVC,MVP,MVVM" class="headerlink" title="MVC,MVP,MVVM"></a>MVC,MVP,MVVM</h2><p>MVC(Model,View,Controller)</p>
<p>M层:处理数据,业务逻辑</p>
<p>V层:处理界面</p>
<p>C层:控制V层和M层的联系</p>
<p>Android中:M层负责处理数据,V层为XML布局文件,C层为Activity控制器,C层持有M层与V层</p>
<h2 id="MVVM哪一层是处理数据的"><a href="#MVVM哪一层是处理数据的" class="headerlink" title="MVVM哪一层是处理数据的"></a>MVVM哪一层是处理数据的</h2><h2 id="HashMap原理"><a href="#HashMap原理" class="headerlink" title="HashMap原理"></a>HashMap原理</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// HashMap put方法</span></span><br><span class="line"><span class="comment">// 1,需要先hash一下key值</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> V <span class="title">put</span><span class="params">(K key, V value)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> putVal(hash(key), key, value, <span class="keyword">false</span>, <span class="keyword">true</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// hash key值</span></span><br><span class="line"><span class="comment">// 用key的hashCode与hashCode的高位进行异或</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> <span class="title">hash</span><span class="params">(Object key)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> h;</span><br><span class="line"> <span class="keyword">return</span> (key == <span class="keyword">null</span>) ? <span class="number">0</span> : (h = key.hashCode()) ^ (h >>> <span class="number">16</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 默认首次put数据的时候,会创建一个table数组,长度为默认16,阈值为16*0.75f = 12,,然后放入并计算需要放入的数据下标 p = tab[i = (n - 1) & hash],此时不会发生碰撞可以放入</span></span><br><span class="line"><span class="comment">// 再次put数据的时候,如果发生了下标碰撞,则判断 hash值,键值是否一致,一致则修改value值</span></span><br><span class="line"><span class="keyword">if</span> (p.hash == hash && ((k = p.key) == key || (key != <span class="keyword">null</span> && key.equals(k))))</span><br><span class="line"><span class="comment">// 如果放入的数据超过阈值,也就是一开始的12,则进行扩容resize(),新扩容的长度为原长度的2倍,新的阈值为原来阈值的2倍,当数组里面有一个链表超过了8,则链表转换成红黑树</span></span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"><span class="comment">// hashMap 获取数据</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> V <span class="title">get</span><span class="params">(Object key)</span> </span>{</span><br><span class="line"> Node<K,V> e;</span><br><span class="line"> <span class="keyword">return</span> (e = getNode(hash(key), key)) == <span class="keyword">null</span> ? <span class="keyword">null</span> : e.value;</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 先计算hash key然后计算在数组中的位置,如果存在,则判断hash值是否相同,在判断key内存地址是否相同,或者equals是否相同,相同则找到value,如果不同,则遍历数组位置下的链表或者红黑树,然后判断</span></span><br></pre></td></tr></table></figure>
<ul>
<li><p>ArrayList原理</p>
<blockquote>
<p>优点:查找效率高,索引遍历快</p>
<p>缺点:插入删除指定位置都要对整个数组进行移动,效率低</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// ArrayList初始化的时候,只是this.elementData指向一个</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="title">ArrayList</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">this</span>.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 首次添加的时候,需要先确认下容量,如果是初始化的,则默认先给10个容量,如果一直添加,超过10个数据,则进行扩容,增加到原来容量的1.5倍</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">add</span><span class="params">(E e)</span> </span>{</span><br><span class="line"> ensureCapacityInternal(size + <span class="number">1</span>); <span class="comment">// Increments modCount!!</span></span><br><span class="line"> elementData[size++] = e;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li>
<li><p>LinkedList原理</p>
<blockquote>
<p>优点:增加和删除快</p>
<p>缺点:查询慢</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// LinkedList初始化</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="title">LinkedList</span><span class="params">()</span> </span>{</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 添加操作</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">add</span><span class="params">(E e)</span> </span>{</span><br><span class="line"> linkLast(e);</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">linkLast</span><span class="params">(E e)</span> </span>{</span><br><span class="line"> <span class="keyword">final</span> Node<E> l = last;</span><br><span class="line"> <span class="keyword">final</span> Node<E> newNode = <span class="keyword">new</span> Node<>(l, e, <span class="keyword">null</span>);</span><br><span class="line"> last = newNode;</span><br><span class="line"> <span class="keyword">if</span> (l == <span class="keyword">null</span>)</span><br><span class="line"> first = newNode;</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> l.next = newNode;</span><br><span class="line"> size++;</span><br><span class="line"> modCount++;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li>
</ul>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="http://example.com/2021/06/19/Android/Jetpack/Compose/Compose/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.jpeg">
<meta itemprop="name" content="Damon">
<meta itemprop="description" content="别走那么快,这样会错过沿途的风景的!">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Damon-Blog">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2021/06/19/Android/Jetpack/Compose/Compose/" class="post-title-link" itemprop="url">Android-Jetpack:Compose</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2021-06-19 16:24:08" itemprop="dateCreated datePublished" datetime="2021-06-19T16:24:08+08:00">2021-06-19</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">更新于</span>
<time title="修改时间:2021-06-21 13:48:45" itemprop="dateModified" datetime="2021-06-21T13:48:45+08:00">2021-06-21</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/Android/" itemprop="url" rel="index"><span itemprop="name">Android</span></a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h1 id="一:-Gradle配置"><a href="#一:-Gradle配置" class="headerlink" title="一: Gradle配置"></a>一: Gradle配置</h1><figure class="highlight groovy"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Kotlin版本必须为1.4.21及以上</span></span><br><span class="line">plugins {</span><br><span class="line"> id <span class="string">'org.jetbrains.kotlin.android'</span> version <span class="string">'1.4.21'</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 配置app的build.gradle</span></span><br><span class="line"><span class="comment">// 1,Api版本设置为21或者更高级别</span></span><br><span class="line"><span class="comment">// 2,启用compose</span></span><br><span class="line"><span class="comment">// 3,设置Kotlin编译器插件版本</span></span><br><span class="line">android {</span><br><span class="line"> </span><br><span class="line"> <span class="comment">// 1</span></span><br><span class="line"> defaultConfig {</span><br><span class="line"> minSdkVersion <span class="number">21</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 2</span></span><br><span class="line"> buildFeatures {</span><br><span class="line"> compose <span class="literal">true</span></span><br><span class="line"> }</span><br><span class="line"> ...</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Set both the Java and Kotlin compilers to target Java 8.</span></span><br><span class="line"></span><br><span class="line"> compileOptions {</span><br><span class="line"> sourceCompatibility JavaVersion.VERSION_1_8</span><br><span class="line"> targetCompatibility JavaVersion.VERSION_1_8</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> kotlinOptions {</span><br><span class="line"> jvmTarget = <span class="string">"1.8"</span></span><br><span class="line"> useIR = <span class="literal">true</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 3</span></span><br><span class="line"> composeOptions {</span><br><span class="line"> kotlinCompilerVersion <span class="string">'1.4.21'</span></span><br><span class="line"> kotlinCompilerExtensionVersion <span class="string">'1.0.0-alpha10'</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 添加配置依赖包</span></span><br><span class="line">dependencies {</span><br><span class="line"> implementation <span class="string">'androidx.compose.ui:ui:1.0.0-alpha10'</span></span><br><span class="line"> <span class="comment">// 工具支持 (Previews, etc.)</span></span><br><span class="line"> implementation <span class="string">'androidx.compose.ui:ui-tooling:1.0.0-alpha10'</span></span><br><span class="line"> <span class="comment">// 基础组件 (Border, Background, Box, Image, Scroll, shapes, animations, etc.)</span></span><br><span class="line"> implementation <span class="string">'androidx.compose.foundation:foundation:1.0.0-alpha10'</span></span><br><span class="line"> <span class="comment">// MD风格</span></span><br><span class="line"> implementation <span class="string">'androidx.compose.material:material:1.0.0-alpha10'</span></span><br><span class="line"> <span class="comment">// MD风格图示</span></span><br><span class="line"> implementation <span class="string">'androidx.compose.material:material-icons-core:1.0.0-alpha10'</span></span><br><span class="line"> implementation <span class="string">'androidx.compose.material:material-icons-extended:1.0.0-alpha10'</span></span><br><span class="line"> <span class="comment">// 可观察数据</span></span><br><span class="line"> implementation <span class="string">'androidx.compose.runtime:runtime-livedata:1.0.0-alpha10'</span></span><br><span class="line"> implementation <span class="string">'androidx.compose.runtime:runtime-rxjava2:1.0.0-alpha10'</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">// UI测试</span></span><br><span class="line"> androidTestImplementation <span class="string">'androidx.compose.ui:ui-test-junit4:1.0.0-alpha10'</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h1 id="二:基础使用"><a href="#二:基础使用" class="headerlink" title="二:基础使用"></a>二:基础使用</h1><h2 id="组件使用:"><a href="#组件使用:" class="headerlink" title="组件使用:"></a>组件使用:</h2><ul>
<li><p>定义可组合函数(使用@Composable)</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Composable</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">Screen</span><span class="params">()</span></span>{</span><br><span class="line"> </span><br><span class="line">}</span><br></pre></td></tr></table></figure></li>
<li><p>显示文本</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Composable</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">MyText</span><span class="params">()</span></span> {</span><br><span class="line"> <span class="keyword">var</span> typography = MaterialTheme.typography</span><br><span class="line"> Text(</span><br><span class="line"> style = typography.h6, <span class="comment">// MD风格文本</span></span><br><span class="line"> maxLines = <span class="number">2</span>, <span class="comment">// 长度上限设置为 2 行</span></span><br><span class="line"> overflow = TextOverflow.Ellipsis, <span class="comment">// 自动截短</span></span><br><span class="line"> text = <span class="string">"A day in Shark Fin Cove"</span>)</span><br><span class="line"> Text(<span class="string">"Davenport, California"</span>)</span><br><span class="line"> Text(<span class="string">"December 2018"</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li>
<li><p>显示列表</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Composable</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">MyTextColumn</span><span class="params">()</span></span> {</span><br><span class="line"> Column {</span><br><span class="line"> Text(<span class="string">"A day in Shark Fin Cove"</span>)</span><br><span class="line"> Text(<span class="string">"Davenport, California"</span>)</span><br><span class="line"> Text(<span class="string">"December 2018"</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li>
<li><p>显示图片</p>
<ul>
<li>contentScale = ContentScale.Crop : 设置图片显示模式</li>
</ul>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Composable</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">MyImageWithMidifier</span><span class="params">()</span></span> {</span><br><span class="line"> <span class="keyword">val</span> painterResource = painterResource(id = R.drawable.ic_launcher_background)</span><br><span class="line"> Image(</span><br><span class="line"> modifier = Modifier</span><br><span class="line"> .height(<span class="number">200.</span>dp)</span><br><span class="line"> .width(<span class="number">200.</span>dp),</span><br><span class="line"> painter = painterResource,</span><br><span class="line"> contentDescription = <span class="literal">null</span>,</span><br><span class="line"> contentScale = ContentScale.Crop</span><br><span class="line"> )</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li>
<li><p>显示分割线</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Spacer(modifier = Modifier.fillMaxWidth().height(<span class="number">10.</span>dp))</span><br></pre></td></tr></table></figure></li>
</ul>
<h2 id="组件修饰:"><a href="#组件修饰:" class="headerlink" title="组件修饰:"></a>组件修饰:</h2><p>使用<code>modifier</code>对组件进行修饰</p>
<ul>
<li><p><code>Padding</code></p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Composable</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">MyTextColumnWithMidifier</span><span class="params">()</span></span> {</span><br><span class="line"> Column(modifier = Modifier.padding(<span class="number">16.</span>dp)) {</span><br><span class="line"> Text(<span class="string">"A day in Shark Fin Cove"</span>)</span><br><span class="line"> Text(<span class="string">"Davenport, California"</span>)</span><br><span class="line"> Text(<span class="string">"December 2018"</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li>
<li><p><code>fillMaxWidth()</code>/<code>fillMaxHeight()</code></p>
</li>
<li><p><code>width()</code>/<code>height()</code></p>
</li>
<li><p><code>clip</code>:裁剪</p>
</li>
</ul>
<h1 id="三:自定义控件"><a href="#三:自定义控件" class="headerlink" title="三:自定义控件"></a>三:自定义控件</h1><h2 id="基础绘制"><a href="#基础绘制" class="headerlink" title="基础绘制"></a>基础绘制</h2><ul>
<li><p>画布</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Canvas(modifier = Modifier.fillMaxSize()) {</span><br><span class="line"> <span class="keyword">val</span> canvasWidth = size.width</span><br><span class="line"> <span class="keyword">val</span> canvasHeight = size.height</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li>
<li><p>画线</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">drawLine(</span><br><span class="line"> start = Offset(x=canvasWidth, y = <span class="number">0f</span>),</span><br><span class="line"> end = Offset(x = <span class="number">0f</span>, y = canvasHeight),</span><br><span class="line"> color = Color.Blue,</span><br><span class="line"> strokeWidth = <span class="number">5F</span></span><br><span class="line">)</span><br></pre></td></tr></table></figure></li>
<li><p>画圆</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">drawCircle(</span><br><span class="line"> color = Color.Blue,</span><br><span class="line"> center = Offset(x = canvasWidth / <span class="number">2</span>, y = canvasHeight / <span class="number">2</span>),</span><br><span class="line"> radius = size.minDimension / <span class="number">4</span></span><br><span class="line">)</span><br></pre></td></tr></table></figure></li>
<li><p>画矩形</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> canvasQuadrantSize = size / <span class="number">2F</span></span><br><span class="line">drawRect(</span><br><span class="line"> color = Color.Green,</span><br><span class="line"> size = canvasQuadrantSize</span><br><span class="line">)</span><br></pre></td></tr></table></figure></li>
</ul>
<h2 id="基础绘制-常用操作"><a href="#基础绘制-常用操作" class="headerlink" title="基础绘制-常用操作"></a>基础绘制-常用操作</h2><ul>
<li><p>insert:绘制的内容垂直偏移量和水平偏移量</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">inset(<span class="number">50F</span>, <span class="number">30F</span>) {</span><br><span class="line"> <span class="comment">// 需要绘制的内容</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure></li>
<li><p>rotate:旋转</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">rotate(degrees = <span class="number">45F</span>){</span><br><span class="line"> <span class="comment">// 需要绘制的内容</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure></li>
<li><p>withTransform:多变化统一变换</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">withTransform({</span><br><span class="line"> translate(left = canvasWidth/<span class="number">5F</span>)</span><br><span class="line"> rotate(degrees=<span class="number">45F</span>)</span><br><span class="line">}) {</span><br><span class="line"> drawRect(</span><br><span class="line"> color = Color.Gray,</span><br><span class="line"> topLeft = Offset(x = canvasWidth / <span class="number">3F</span>, y = canvasHeight / <span class="number">3F</span>),</span><br><span class="line"> size = canvasSize / <span class="number">3F</span></span><br><span class="line"> )</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li>
</ul>
<h1 id="四:动画"><a href="#四:动画" class="headerlink" title="四:动画"></a>四:动画</h1><ul>
<li>AnimatedVisibility:可见不可见动画</li>
<li>animateContentSize:内容修改动画</li>
<li>Crossfade:</li>
<li>animate*AsState</li>
</ul>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Composable</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">MyView</span><span class="params">()</span></span>{</span><br><span class="line"> Canvas(modifier = Modifier.fillMaxSize()) {</span><br><span class="line"> <span class="keyword">val</span> canvasWidth = size.width</span><br><span class="line"> <span class="keyword">val</span> canvasHeight = size.height</span><br><span class="line"></span><br><span class="line"> drawLine(</span><br><span class="line"> start = Offset(x=canvasWidth, y = <span class="number">0f</span>),</span><br><span class="line"> end = Offset(x = <span class="number">0f</span>, y = canvasHeight),</span><br><span class="line"> color = Color.Blue,</span><br><span class="line"> strokeWidth = <span class="number">5F</span></span><br><span class="line"> )</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h1 id="常用内置界面"><a href="#常用内置界面" class="headerlink" title="常用内置界面"></a>常用内置界面</h1><table>
<thead>
<tr>
<th>内置Compose</th>
<th>功能</th>
</tr>
</thead>
<tbody><tr>
<td>Surface</td>
<td>添加背景色</td>
</tr>
<tr>
<td>Button</td>
<td>按钮</td>
</tr>
<tr>
<td>Text</td>
<td>文本</td>
</tr>
<tr>
<td>Column</td>
<td>垂直放置项目</td>
</tr>
<tr>
<td>ScrollableColumn</td>
<td>可滚动垂直放置项目,== ScrollView</td>
</tr>
<tr>
<td>LazyColumn</td>
<td>可滚动垂直放置项目,== RecycleView,惰性加载</td>
</tr>
<tr>
<td>Divider</td>
<td>分割线</td>
</tr>
<tr>
<td>Row</td>
<td>水平放置项目</td>
</tr>
<tr>
<td>TopAppBar</td>
<td>顶部导航栏</td>
</tr>
<tr>
<td>Scaffold</td>
<td>允许您使用基本的Material Design布局结构来实现UI</td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</tbody></table>
<h1 id="常用的功能"><a href="#常用的功能" class="headerlink" title="常用的功能"></a>常用的功能</h1><table>
<thead>
<tr>
<th>内置功能</th>
<th>功能</th>
</tr>
</thead>
<tbody><tr>
<td>remember</td>
<td>可变状态</td>
</tr>
<tr>
<td>mutableStateOf</td>
<td>可组合可变存储器函数</td>
</tr>
<tr>
<td>animateColorAsState</td>
<td>动画</td>
</tr>
</tbody></table>
<h1 id="基础:"><a href="#基础:" class="headerlink" title="基础:"></a>基础:</h1><h2 id="第一课:可组合函数"><a href="#第一课:可组合函数" class="headerlink" title="第一课:可组合函数"></a>第一课:可组合函数</h2><blockquote>
<p> 只需要将 <code>@Composable</code> 添加到函数名称中即可创建可组合函数</p>
<p>添加 <code>@Preview</code> 即可预览函数,注意要加在不带参数的可组合函数中</p>
</blockquote>
<p>定义可组合函数</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MainActivity</span> : <span class="type">AppCompatActivity</span></span>() {</span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onCreate</span><span class="params">(savedInstanceState: <span class="type">Bundle</span>?)</span></span> {</span><br><span class="line"> <span class="keyword">super</span>.onCreate(savedInstanceState)</span><br><span class="line"> setContent {</span><br><span class="line"> <span class="comment">// 调用可组合函数</span></span><br><span class="line"> Greeting(<span class="string">"Android"</span>)</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 定义可组合函数</span></span><br><span class="line"><span class="meta">@Composable</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">Greeting</span><span class="params">(name: <span class="type">String</span>)</span></span> {</span><br><span class="line"> Text (text = <span class="string">"Hello <span class="variable">$name</span>!"</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="第二课:布局"><a href="#第二课:布局" class="headerlink" title="第二课:布局"></a>第二课:布局</h2><p>Column:可垂直堆叠元素</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MainActivity</span> : <span class="type">AppCompatActivity</span></span>() {</span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onCreate</span><span class="params">(savedInstanceState: <span class="type">Bundle</span>?)</span></span> {</span><br><span class="line"> <span class="keyword">super</span>.onCreate(savedInstanceState)</span><br><span class="line"> setContent {</span><br><span class="line"> NewsStory()</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Composable</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">NewsStory</span><span class="params">()</span></span> {</span><br><span class="line"> Column {</span><br><span class="line"> Text(<span class="string">"A day in Shark Fin Cove"</span>)</span><br><span class="line"> Text(<span class="string">"Davenport, California"</span>)</span><br><span class="line"> Text(<span class="string">"December 2018"</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>Column:使用 <code>Modifier</code> 添加样式,可配置尺寸和位置,以及排列方式</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Composable</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">NewsStory</span><span class="params">()</span></span> {</span><br><span class="line"> Column(</span><br><span class="line"> modifier = Modifier.padding(<span class="number">16.</span>dp)</span><br><span class="line"> ) {</span><br><span class="line"> Text(<span class="string">"A day in Shark Fin Cove"</span>)</span><br><span class="line"> Text(<span class="string">"Davenport, California"</span>)</span><br><span class="line"> Text(<span class="string">"December 2018"</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>Column:添加图片</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Composable</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">NewsStory</span><span class="params">()</span></span> {</span><br><span class="line"> <span class="comment">// 从资源文件夹中获取图片</span></span><br><span class="line"> <span class="keyword">val</span> image = imageResource(R.drawable.header)</span><br><span class="line"></span><br><span class="line"> Column(</span><br><span class="line"> modifier = Modifier.padding(<span class="number">16.</span>dp)</span><br><span class="line"> ) {</span><br><span class="line"> <span class="comment">// 设置图片</span></span><br><span class="line"> Image(image)</span><br><span class="line"></span><br><span class="line"> Text(<span class="string">"A day in Shark Fin Cove"</span>)</span><br><span class="line"> Text(<span class="string">"Davenport, California"</span>)</span><br><span class="line"> Text(<span class="string">"December 2018"</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>Column:修改图片样式</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Composable</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">NewsStory</span><span class="params">()</span></span> {</span><br><span class="line"> <span class="keyword">val</span> image = imageResource(R.drawable.header)</span><br><span class="line"> Column(</span><br><span class="line"> modifier = Modifier.padding(<span class="number">16.</span>dp)</span><br><span class="line"> ) {</span><br><span class="line"> <span class="keyword">val</span> imageModifier = Modifier</span><br><span class="line"> .preferredHeight(<span class="number">180.</span>dp) <span class="comment">// 指定图片的高度</span></span><br><span class="line"> .fillMaxWidth() <span class="comment">// 指定图片的宽度可以填充所属布局</span></span><br><span class="line"></span><br><span class="line"> Image(image,</span><br><span class="line"> modifier = imageModifier,</span><br><span class="line"> contentScale = ContentScale.Crop) <span class="comment">// 指定图片填充Column整个宽度,根据需要裁剪为适当的高度</span></span><br><span class="line"></span><br><span class="line"> Text(<span class="string">"A day in Shark Fin Cove"</span>)</span><br><span class="line"> Text(<span class="string">"Davenport, California"</span>)</span><br><span class="line"> Text(<span class="string">"December 2018"</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>Column:添加Spacer分割线,将图片和标题分开</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Composable</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">NewsStory</span><span class="params">()</span></span> {</span><br><span class="line"> <span class="keyword">val</span> image = imageResource(R.drawable.header)</span><br><span class="line"> Column(</span><br><span class="line"> modifier = Modifier.padding(<span class="number">16.</span>dp)</span><br><span class="line"> ) {</span><br><span class="line"> <span class="keyword">val</span> imageModifier = Modifier</span><br><span class="line"> .preferredHeight(<span class="number">180.</span>dp)</span><br><span class="line"> .fillMaxWidth()</span><br><span class="line"></span><br><span class="line"> Image(image,</span><br><span class="line"> modifier = imageModifier,</span><br><span class="line"> contentScale = ContentScale.Crop)</span><br><span class="line"> <span class="comment">// 添加分割线</span></span><br><span class="line"> Spacer(Modifier.preferredHeight(<span class="number">16.</span>dp))</span><br><span class="line"></span><br><span class="line"> Text(<span class="string">"A day in Shark Fin Cove"</span>)</span><br><span class="line"> Text(<span class="string">"Davenport, California"</span>)</span><br><span class="line"> Text(<span class="string">"December 2018"</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="第三课:Material-Design"><a href="#第三课:Material-Design" class="headerlink" title="第三课:Material Design"></a>第三课:Material Design</h2><p>主要关键要素: <code>Shape</code> </p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Composable</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">NewsStory</span><span class="params">()</span></span> {</span><br><span class="line"> <span class="keyword">val</span> image = imageResource(R.drawable.header)</span><br><span class="line"> Column(</span><br><span class="line"> modifier = Modifier.padding(<span class="number">16.</span>dp)</span><br><span class="line"> ) {</span><br><span class="line"> <span class="keyword">val</span> imageModifier = Modifier</span><br><span class="line"> .preferredHeight(<span class="number">180.</span>dp)</span><br><span class="line"> .fillMaxWidth()</span><br><span class="line"> .clip(shape = RoundedCornerShape(<span class="number">4.</span>dp)) <span class="comment">// 设置圆角裁切</span></span><br><span class="line"></span><br><span class="line"> Image(image,</span><br><span class="line"> modifier = imageModifier,</span><br><span class="line"> contentScale = ContentScale.Crop)</span><br><span class="line"> Spacer(Modifier.preferredHeight(<span class="number">16.</span>dp))</span><br><span class="line"></span><br><span class="line"> Text(<span class="string">"A day in Shark Fin Cove"</span>)</span><br><span class="line"> Text(<span class="string">"Davenport, California"</span>)</span><br><span class="line"> Text(<span class="string">"December 2018"</span>)</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>使用<code>Material主题</code>设置文本样式</p>
<ul>
<li>MaterialTheme.typography</li>
</ul>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Composable</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">NewsStory</span><span class="params">()</span></span> {</span><br><span class="line"> <span class="keyword">val</span> image = imageResource(R.drawable.header)</span><br><span class="line"> MaterialTheme {</span><br><span class="line"> <span class="comment">// 获取Material的默认文本样式</span></span><br><span class="line"> <span class="keyword">val</span> typography = MaterialTheme.typography</span><br><span class="line"> Column(</span><br><span class="line"> modifier = Modifier.padding(<span class="number">16.</span>dp)</span><br><span class="line"> ) {</span><br><span class="line"> <span class="keyword">val</span> imageModifier = Modifier</span><br><span class="line"> .preferredHeight(<span class="number">180.</span>dp)</span><br><span class="line"> .fillMaxWidth()</span><br><span class="line"> .clip(shape = RoundedCornerShape(<span class="number">4.</span>dp))</span><br><span class="line"></span><br><span class="line"> Image(image,</span><br><span class="line"> modifier = imageModifier,</span><br><span class="line"> contentScale = ContentScale.Crop)</span><br><span class="line"> Spacer(Modifier.preferredHeight(<span class="number">16.</span>dp))</span><br><span class="line"></span><br><span class="line"> Text(<span class="string">"A day in Shark Fin Cove"</span>,</span><br><span class="line"> style = typography.h6) <span class="comment">// 设置文本样式</span></span><br><span class="line"> Text(<span class="string">"Davenport, California"</span>,</span><br><span class="line"> style = typography.body2)</span><br><span class="line"> Text(<span class="string">"December 2018"</span>,</span><br><span class="line"> style = typography.body2)</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>如果标题文本过长则进行截断配置</p>
<p>属性设置</p>
<ul>
<li>maxLines</li>
<li>overflow</li>
</ul>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Composable</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">NewsStory</span><span class="params">()</span></span> {</span><br><span class="line"> <span class="keyword">val</span> image = imageResource(R.drawable.header)</span><br><span class="line"> MaterialTheme {</span><br><span class="line"> <span class="keyword">val</span> typography = MaterialTheme.typography</span><br><span class="line"> Column(</span><br><span class="line"> modifier = Modifier.padding(<span class="number">16.</span>dp)</span><br><span class="line"> ) {</span><br><span class="line"> <span class="keyword">val</span> imageModifier = Modifier</span><br><span class="line"> .preferredHeight(<span class="number">180.</span>dp)</span><br><span class="line"> .fillMaxWidth()</span><br><span class="line"> .clip(shape = RoundedCornerShape(<span class="number">4.</span>dp))</span><br><span class="line"></span><br><span class="line"> Image(image,</span><br><span class="line"> modifier = imageModifier,</span><br><span class="line"> contentScale = ContentScale.Crop)</span><br><span class="line"> Spacer(Modifier.preferredHeight(<span class="number">16.</span>dp))</span><br><span class="line"></span><br><span class="line"> Text(</span><br><span class="line"> <span class="string">"A day wandering through the sandhills "</span> +</span><br><span class="line"> <span class="string">"in Shark Fin Cove, and a few of the "</span> +</span><br><span class="line"> <span class="string">"sights I saw"</span>,</span><br><span class="line"> style = typography.h6,</span><br><span class="line"> maxLines = <span class="number">2</span>, <span class="comment">// 设置文本2行</span></span><br><span class="line"> overflow = TextOverflow.Ellipsis) <span class="comment">// 设置文本超出部分后面...显示</span></span><br><span class="line"> Text(<span class="string">"Davenport, California"</span>,</span><br><span class="line"> style = typography.body2)</span><br><span class="line"> Text(<span class="string">"December 2018"</span>,</span><br><span class="line"> style = typography.body2)</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h1 id="State"><a href="#State" class="headerlink" title="State"></a>State</h1><h2 id="初步使用"><a href="#初步使用" class="headerlink" title="初步使用"></a>初步使用</h2><p>Compose UI的数据变化通过可观察状态来实现,常用的有State, LiveData, StateFlow, Flow, Observable</p>
<ul>
<li>ViewModel+LiveData+Activity</li>
</ul>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">HelloViewModel</span>: <span class="type">ViewModel</span></span>(){</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">val</span> _name = MutableLiveData(<span class="string">""</span>)</span><br><span class="line"> <span class="keyword">val</span> name: LiveData<String> = _name</span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">onNameChanged</span><span class="params">(newName: <span class="type">String</span>)</span></span>{</span><br><span class="line"> _name.value = newName</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">HelloActivity</span>: <span class="type">AppCompatActivity</span></span>(){</span><br><span class="line"> <span class="keyword">val</span> helloViewModel <span class="keyword">by</span> viewModels<HelloViewModel>()</span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">onCreate</span><span class="params">(saveInstanceState: <span class="type">Bundle</span>?)</span></span>{</span><br><span class="line"> <span class="keyword">super</span>.onCreate(saveInstanceState)</span><br><span class="line"> binding.textInput.doAfterTextChanged{</span><br><span class="line"> helloViewModel.onNameChanged(it.toString)</span><br><span class="line"> }</span><br><span class="line"> helloViewModel.name.observe(<span class="keyword">this</span>){ name -> </span><br><span class="line"> binding.helloText.text = <span class="string">"Hello, <span class="variable">$name</span>"</span></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<ul>
<li><p>ViewModel + Compose + Activity</p>
<blockquote>
<p><code>observeAsState</code> 可观察 <code>LiveData<T></code> 并返回 <a target="_blank" rel="noopener" href="https://developer.android.google.cn/reference/kotlin/androidx/compose/runtime/State"><code>State</code></a> 对象,每当 <code>LiveData</code> 发生变化时,该对象都会更新。<code>State<T></code> 是 Jetpack Compose 可以直接使用的可观察类型</p>
</blockquote>
</li>
</ul>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">HelloViewModel</span>: <span class="type">ViewModel</span></span>(){</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">val</span> _name = MutableLiveData(<span class="string">""</span>)</span><br><span class="line"> <span class="keyword">val</span> name: LiveData<String> = _name</span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">onNameChanged</span><span class="params">(newName: <span class="type">String</span>)</span></span>{</span><br><span class="line"> _name.value = newName</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Composable</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">HelloScreen</span><span class="params">(helloViewModel: <span class="type">HelloViewModel</span> = viewModel()</span></span>){</span><br><span class="line"> <span class="comment">// 使用委托属性by隐式将State<T>视为类型T的对象</span></span><br><span class="line"> <span class="comment">// val nameState: State<String> = helloViewModel.name.observeAsState("")</span></span><br><span class="line"> <span class="keyword">val</span> name: String <span class="keyword">by</span> helloViewModel.name.onserveAsState(<span class="string">""</span>)</span><br><span class="line"> Column{</span><br><span class="line"> Text(text = name)</span><br><span class="line"> TextField(</span><br><span class="line"> value = name,</span><br><span class="line"> onValueChange = {helloViewModel.onNameChanged(it)},</span><br><span class="line"> label = {Text(<span class="string">"Name"</span>)}</span><br><span class="line"> )</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="可组合项的状态"><a href="#可组合项的状态" class="headerlink" title="可组合项的状态"></a>可组合项的状态</h2><p>使用remember在可组合项中创建内部状态</p>
<ul>
<li><p>添加状态</p>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 在可组合项中声明MutableState对象的方法有三种</span></span><br><span class="line"><span class="keyword">var</span> mutableState = remember { mutableStateOf(default) }</span><br><span class="line"><span class="keyword">var</span> value <span class="keyword">by</span> remember { mutableStateOf(default) }</span><br><span class="line"><span class="keyword">val</span> (value, setValue) = remember{ mutableStateOf(default) }</span><br><span class="line"></span><br><span class="line"><span class="comment">// 注意</span></span><br><span class="line"><span class="comment">// = 跟 by 是不同的</span></span><br></pre></td></tr></table></figure></li>
</ul>
<h2 id="其他状态"><a href="#其他状态" class="headerlink" title="其他状态"></a>其他状态</h2><p>Jetpack Compose 并不要求您使用<code>MutableState<T></code>存储状态,Jetpack Compose支持其它可观察类型,不过在读取其它可观察类型之前,需要转换成<code>State<T></code>,才能在发生状态变化时自动重组界面,其它可观察类型如下:</p>
<ul>
<li>LiveData</li>
<li>Flow</li>
<li>RxJava2</li>
</ul>
<blockquote>
<p>注意:可变对象(ArrayList<T>或者mutableListOf())可能会导致看到不正确的数据,不可变数据不能由Compose观察,因为发生变化时不能进行重组,需要使用可观察的存储器(State<List<T>>)和不可变的listOf()</p>
</blockquote>
<h2 id="注意事项"><a href="#注意事项" class="headerlink" title="注意事项"></a>注意事项</h2><p>1,在组合中被<code>remember</code>记住的值在配置更改(如旋转)的时候会被忘记并重新创建,可以改用保存的实例状态,在配置更改的时候自动保存和恢复状态</p>
<ul>
<li><p>savedInstanceState</p>
<blockquote>
<p>可组合函数 savedInstanceState<T> 会返回MutableState<T>,它会在配置更改时自动保存和恢复自身</p>
</blockquote>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Composable</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">ExpandingCard</span><span class="params">(title: <span class="type">String</span>, body: <span class="type">String</span>)</span></span> {</span><br><span class="line"> <span class="keyword">var</span> expanded <span class="keyword">by</span> savedInstanceState { <span class="literal">false</span> }</span><br><span class="line"> ExpandingCard(</span><br><span class="line"> title = title,</span><br><span class="line"> body = body,</span><br><span class="line"> expanded = expanded,</span><br><span class="line"> onExpand = { expanded = <span class="literal">true</span> },</span><br><span class="line"> onCollapse = { expanded = <span class="literal">false</span> }</span><br><span class="line"> )</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li>
</ul>
<p> </p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="http://example.com/2021/06/19/Android/Kotlin/Kotlin%E8%AF%AD%E6%B3%95%E5%BF%AB%E9%80%9F%E5%AD%A6%E4%B9%A0/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.jpeg">
<meta itemprop="name" content="Damon">
<meta itemprop="description" content="别走那么快,这样会错过沿途的风景的!">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Damon-Blog">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2021/06/19/Android/Kotlin/Kotlin%E8%AF%AD%E6%B3%95%E5%BF%AB%E9%80%9F%E5%AD%A6%E4%B9%A0/" class="post-title-link" itemprop="url">Kotlin-语法快速学习</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2021-06-19 16:24:08" itemprop="dateCreated datePublished" datetime="2021-06-19T16:24:08+08:00">2021-06-19</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">更新于</span>
<time title="修改时间:2021-06-21 14:00:01" itemprop="dateModified" datetime="2021-06-21T14:00:01+08:00">2021-06-21</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/Android-Kotlin/" itemprop="url" rel="index"><span itemprop="name">Android Kotlin</span></a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h1 id="基础入门"><a href="#基础入门" class="headerlink" title="基础入门"></a>基础入门</h1><h2 id="基本类型:"><a href="#基本类型:" class="headerlink" title="基本类型:"></a>基本类型:</h2><ul>
<li>数字<ul>
<li>Byte</li>
<li>Short</li>
<li>Int</li>
<li>Long</li>
<li>Float</li>
<li>Double</li>
</ul>
</li>
<li>字符<ul>
<li>Char</li>
</ul>
</li>
<li>布尔<ul>
<li>Boolean</li>
</ul>
</li>
<li>数组<ul>
<li>Array</li>
</ul>
</li>
<li>字符串<ul>
<li>String</li>
</ul>
</li>
</ul>
<blockquote>
<p>1,每个数字类型都支持toXXX()转换</p>
<p>2,Int 与 Long才拥有位运算:shl(有符号左移) shr(有符号右移) ushr(无符号右移) and(位与) or(位或) xor(位异或) inv(位非)</p>
<p>3,原声类型数组:ByteArray,ShortArray,IntArray</p>
</blockquote>
<h2 id="控制流(if,when,for,while)"><a href="#控制流(if,when,for,while)" class="headerlink" title="控制流(if,when,for,while)"></a>控制流(if,when,for,while)</h2><blockquote>
<p>if</p>
</blockquote>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// if关键字</span></span><br><span class="line"><span class="comment">// 常规if</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">maxOf</span><span class="params">(a:<span class="type">Int</span>, b:<span class="type">Int</span>)</span></span>: <span class="built_in">Int</span>{</span><br><span class="line"> <span class="keyword">if</span>(a > b){</span><br><span class="line"> <span class="keyword">return</span> a</span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> retuan b</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 简化</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">maxOf</span><span class="params">(a:<span class="type">Int</span>, b:<span class="type">Int</span>)</span></span> = <span class="keyword">if</span>(a > b) a <span class="keyword">else</span> b</span><br></pre></td></tr></table></figure>
<blockquote>
<p>when</p>
</blockquote>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// when关键字</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">describe</span><span class="params">(obj:<span class="type">Any</span>)</span></span>:String = </span><br><span class="line"> <span class="keyword">when</span>(obj){</span><br><span class="line"> <span class="number">1</span> -> <span class="string">"One"</span></span><br><span class="line"> <span class="string">"Hello"</span> -> <span class="string">"Greeting"</span></span><br><span class="line"> <span class="keyword">is</span> <span class="built_in">Long</span> -> <span class="string">"Long"</span></span><br><span class="line"> !<span class="keyword">is</span> String -> <span class="string">"Not a string"</span></span><br><span class="line"> <span class="keyword">else</span> -> <span class="string">"Unknown"</span></span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
<blockquote>
<p>for</p>
</blockquote>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// for in关键字</span></span><br><span class="line"><span class="keyword">val</span> items = listOf(<span class="string">"A"</span>,<span class="string">"B"</span>,<span class="string">"C"</span>)</span><br><span class="line"><span class="keyword">for</span>(item <span class="keyword">in</span> items){</span><br><span class="line"> println(item)</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 带有下标的for</span></span><br><span class="line"><span class="keyword">for</span>(index <span class="keyword">in</span> items.indices){</span><br><span class="line"> println(<span class="string">"item at <span class="variable">$index</span> is $(items[index])"</span>)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 遍历map</span></span><br><span class="line"><span class="keyword">for</span>((k, v) <span class="keyword">in</span> map){</span><br><span class="line"> print(<span class="string">"<span class="variable">$k</span> -> <span class="variable">$v</span>"</span>)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// for可以对任何提供了迭代器的对象进行遍历</span></span><br><span class="line"><span class="comment">// 即</span></span><br><span class="line"><span class="comment">// 有一个成员函数或者扩展函数 iterator(),它的返回类型</span></span><br><span class="line"><span class="comment">// - 有一个成员函数或者扩展函数 next(),并且</span></span><br><span class="line"><span class="comment">// - 有一个成员函数或者扩展函数 hasNext() 返回 Boolean</span></span><br><span class="line"><span class="comment">// 这三个函数都需要标记为 operator</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>while</p>
</blockquote>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// while 关键字</span></span><br><span class="line"><span class="keyword">val</span> items = listOf(<span class="string">"A"</span>, <span class="string">"B"</span>, <span class="string">"C"</span>)</span><br><span class="line"><span class="keyword">var</span> index = <span class="number">0</span></span><br><span class="line"><span class="keyword">while</span>(index < items.size){</span><br><span class="line"> println(<span class="string">"item at <span class="variable">$index</span> is $(items[index])"</span>)</span><br><span class="line"> index++</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="类"><a href="#类" class="headerlink" title="类"></a>类</h2><h3 id="类-1"><a href="#类-1" class="headerlink" title="类"></a>类</h3><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 编写一个类</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Invoice</span></span>{}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 主构造函数</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Person</span> <span class="keyword">constructor</span></span>(firstName:String){}</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Persion</span></span>(firstName:String) <span class="comment">// 没有注解或者可见修饰符则可以省略constructor</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Person</span></span>(firstName:String){</span><br><span class="line"> <span class="keyword">val</span> name = firstName <span class="comment">// 属性初始化器可使用主构造函数参数</span></span><br><span class="line"> <span class="keyword">init</span>{</span><br><span class="line"> name = firstName <span class="comment">// 初始化块可使用主构造函数参数</span></span><br><span class="line"> <span class="comment">// 初始化块</span></span><br><span class="line"> ...</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Person</span></span>(<span class="keyword">val</span> firstName:String, <span class="keyword">val</span> lastName: String, <span class="keyword">var</span> age: <span class="built_in">Int</span>){} <span class="comment">// 属性直接在构造函数中声明(可声明为 var 或 val)</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Person</span> <span class="keyword">public</span> <span class="meta">@Inject</span> <span class="keyword">constructor</span></span>(){} <span class="comment">// 构造函数有注解或者可见性修饰符,constructor不能省略</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 次构造函数</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Person</span>(<span class="title">val</span> <span class="title">name</span>:<span class="type">String){</span></span></span><br><span class="line"> <span class="keyword">constructor</span>(name: String, age: <span class="built_in">Int</span>): <span class="keyword">this</span>(name) { <span class="comment">// 次构造函数,次构造函数委托到另一个构造函数用this</span></span><br><span class="line"> </span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建类的实例</span></span><br><span class="line"><span class="keyword">val</span> person = Person()</span><br><span class="line"></span><br><span class="line"><span class="comment">// 继承</span></span><br><span class="line"><span class="comment">// 在Kotlin中,所有类都有一个共同的超类Any,Any有三个方法:equals/hashCode/toString</span></span><br><span class="line"><span class="comment">// 默认情况下,kotlin的类是final的,不能被继承,如果需要被继承,需要使用关键字 open</span></span><br><span class="line"><span class="keyword">open</span> <span class="class"><span class="keyword">class</span> <span class="title">Base</span></span></span><br><span class="line"><span class="keyword">open</span> <span class="class"><span class="keyword">class</span> <span class="title">Base</span></span>(p:<span class="built_in">Int</span>)</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">A</span></span>(p:<span class="built_in">Int</span>) : Base(p)</span><br><span class="line"><span class="comment">// 如果派生类有一个主构造函数,则基类必须用派生类主构造函数参数初始化</span></span><br><span class="line"><span class="comment">// 如果没有主构造,则每个次构造都需要使用super关键字初始化</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyView</span> :<span class="type">View{</span></span></span><br><span class="line"> <span class="keyword">constructor</span>(ctx: Context) : <span class="keyword">super</span>(ctx)</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 方法覆盖</span></span><br><span class="line"><span class="comment">// 类中函数没有标注open则子类不允许定义相同签名的函数,子类需要在覆盖方法前添加override</span></span><br><span class="line"><span class="comment">// 如果子类需要禁止再次覆盖,可使用final</span></span><br><span class="line"><span class="comment">// 属性覆盖</span></span><br><span class="line"><span class="comment">// 同方法覆盖</span></span><br></pre></td></tr></table></figure>
<h3 id="类中属性"><a href="#类中属性" class="headerlink" title="类中属性"></a>类中属性</h3><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// val - 只读变量</span></span><br><span class="line"><span class="comment">// var - 可重新赋值</span></span><br><span class="line"><span class="comment">// const - 编译器常量,只读属性的值在编译器的时候已知可使用</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Person</span></span>{</span><br><span class="line"> <span class="keyword">var</span> name: String = <span class="string">"A"</span></span><br><span class="line">}</span><br><span class="line"><span class="keyword">val</span> person = Person()</span><br><span class="line">print(person.name)</span><br><span class="line"></span><br><span class="line"><span class="comment">// getter setter</span></span><br><span class="line"><span class="comment">// 自定义getter</span></span><br><span class="line"><span class="keyword">val</span> isEmpty: <span class="built_in">Boolean</span></span><br><span class="line"> <span class="keyword">get</span>() = <span class="keyword">this</span>.size == <span class="number">0</span></span><br><span class="line"><span class="comment">// 自定义setter</span></span><br><span class="line"><span class="keyword">var</span> stringRepresentation: String</span><br><span class="line"> <span class="keyword">get</span>() = <span class="keyword">this</span>.toString()</span><br><span class="line"> <span class="keyword">set</span>(value){</span><br><span class="line"> setDataFromString(value)</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"><span class="comment">// 延迟初始化属性,关键字lateinit</span></span><br><span class="line"><span class="comment">// lateinit</span></span><br><span class="line"><span class="comment">// 只能用于类体中的属性,也可用于顶层属性与局部变量,必须为非空类型,不能为原生类型</span></span><br><span class="line"><span class="comment">// 检测是否初始化 if(xx.isInitialized)</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Test</span></span>{</span><br><span class="line"> <span class="keyword">lateinit</span> <span class="keyword">var</span> obj: Any</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="接口"><a href="#接口" class="headerlink" title="接口"></a>接口</h3><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 关键字 interface</span></span><br><span class="line"><span class="class"><span class="keyword">interface</span> <span class="title">MyInterface</span></span>{</span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">test1</span><span class="params">()</span></span></span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">test2</span><span class="params">()</span></span>{</span><br><span class="line"> </span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 实现接口</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">A</span> : <span class="type">MyInterface{</span></span></span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">test1</span><span class="params">()</span></span>{</span><br><span class="line"> </span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 接口属性,要么是抽象的,要么提供访问器</span></span><br><span class="line"><span class="class"><span class="keyword">interface</span> <span class="title">MyInterface</span></span>{</span><br><span class="line"> <span class="keyword">val</span> prop: <span class="built_in">Int</span> <span class="comment">// 抽象的</span></span><br><span class="line"> <span class="keyword">val</span> propWithImpl: String <span class="comment">// 提供访问器</span></span><br><span class="line"> <span class="keyword">get</span>() = <span class="string">"foo"</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 接口继承</span></span><br><span class="line"><span class="class"><span class="keyword">interface</span> <span class="title">Named</span></span>{</span><br><span class="line"> <span class="keyword">val</span> name: String</span><br><span class="line">}</span><br><span class="line"><span class="class"><span class="keyword">interface</span> <span class="title">Person</span>: <span class="type">Named{</span></span></span><br><span class="line"> <span class="keyword">val</span> firstName: String</span><br><span class="line"> <span class="keyword">val</span> lastName: String</span><br><span class="line"> <span class="keyword">override</span> <span class="keyword">val</span> name: String <span class="keyword">get</span>() = <span class="string">"<span class="variable">$firstName</span> <span class="variable">$lastName</span>"</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">data</span> <span class="class"><span class="keyword">class</span> <span class="title">My</span></span>{</span><br><span class="line"> <span class="comment">// 不必实现“name”</span></span><br><span class="line"> <span class="keyword">override</span> <span class="keyword">val</span> firstName: String,</span><br><span class="line"> <span class="keyword">override</span> <span class="keyword">val</span> lastName: String,</span><br><span class="line"> <span class="keyword">val</span> position: Position</span><br><span class="line">}: Person</span><br><span class="line"></span><br><span class="line"><span class="comment">// 函数式(SAM)接口</span></span><br><span class="line"><span class="comment">// 可以有多个非抽象成员,但只能有一个抽象成员</span></span><br><span class="line"><span class="comment">// fun 声明一个函数式接口</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="keyword">interface</span> KRunnable{</span></span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">invoke</span><span class="params">()</span></span></span><br><span class="line">}</span><br><span class="line"><span class="comment">// 函数式接口通过Lambda表达式实现SAM转换</span></span><br><span class="line"><span class="comment">// 1,声明一个函数式接口</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="keyword">interface</span> IntPredicate {</span></span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">accept</span><span class="params">(i: <span class="type">Int</span>)</span></span>: <span class="built_in">Boolean</span></span><br><span class="line">}</span><br><span class="line"><span class="comment">// 不使用SAM转换的样子,使用匿名类</span></span><br><span class="line"><span class="keyword">val</span> isEven = <span class="keyword">object</span> : IntPredicate {</span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">accept</span><span class="params">(i: <span class="type">Int</span>)</span></span>: <span class="built_in">Boolean</span> {</span><br><span class="line"> <span class="keyword">return</span> i % <span class="number">2</span> == <span class="number">0</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 使用SAM</span></span><br><span class="line"><span class="keyword">val</span> isEven = IntPredicate { it % <span class="number">2</span> == <span class="number">0</span> }</span><br><span class="line">isEven.accept(<span class="number">7</span>)</span><br></pre></td></tr></table></figure>
<h3 id="扩展"><a href="#扩展" class="headerlink" title="扩展"></a>扩展</h3><blockquote>
<p>可以给一个不能修改的来自第三方库的类编写一个新的函数,使得可以直接用 对象.函数 调用</p>
</blockquote>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 声明一个扩展函数</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> MutableList<span class="type"><Int></span>.<span class="title">swap</span><span class="params">(index1: <span class="type">Int</span>, index2: <span class="type">Int</span>)</span></span> {</span><br><span class="line"> <span class="keyword">val</span> tmp = <span class="keyword">this</span>[index1] <span class="comment">// “this”对应该列表</span></span><br><span class="line"> <span class="keyword">this</span>[index1] = <span class="keyword">this</span>[index2]</span><br><span class="line"> <span class="keyword">this</span>[index2] = tmp</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 调用这个扩展函数</span></span><br><span class="line"><span class="keyword">val</span> list = mutableListOf(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>)</span><br><span class="line">list.swap(<span class="number">0</span>, <span class="number">2</span>) <span class="comment">// “swap()”内部的“this”会保存“list”的值</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 注意,扩展函数式静态解析的</span></span><br><span class="line"><span class="comment">// 即 调用的扩展函数是由函数调用所在的表达式的类型来决定的, 而不是由表达式运行时求值结果决定的</span></span><br></pre></td></tr></table></figure>
<h3 id="数据类"><a href="#数据类" class="headerlink" title="数据类"></a>数据类</h3><blockquote>
<p>保存数据的类</p>
</blockquote>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 声明一个数据类</span></span><br><span class="line"><span class="keyword">data</span> <span class="class"><span class="keyword">class</span> <span class="title">Person</span></span>(<span class="keyword">val</span> name: String = <span class="string">""</span>, <span class="keyword">val</span> age: <span class="built_in">Int</span> = <span class="number">0</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 类体中声明的属性不会应用于toString/equals/hashoCode/copy</span></span><br><span class="line"><span class="keyword">data</span> <span class="class"><span class="keyword">class</span> <span class="title">Person</span></span>(<span class="keyword">val</span> name: String){</span><br><span class="line"> <span class="keyword">var</span> age: <span class="built_in">Int</span> = <span class="number">0</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="密封类"><a href="#密封类" class="headerlink" title="密封类"></a>密封类</h3><blockquote>
<p>一种枚举类</p>
</blockquote>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 关键字 sealed</span></span><br><span class="line"><span class="keyword">sealed</span> <span class="class"><span class="keyword">class</span> <span class="title">Expr</span></span></span><br><span class="line"><span class="keyword">data</span> <span class="class"><span class="keyword">class</span> <span class="title">Const</span></span>(<span class="keyword">val</span> number: <span class="built_in">Double</span>) : Expr()</span><br><span class="line"><span class="keyword">data</span> <span class="class"><span class="keyword">class</span> <span class="title">Sum</span></span>(<span class="keyword">val</span> e1: Expr, <span class="keyword">val</span> e2: Expr) : Expr()</span><br><span class="line"><span class="keyword">object</span> NotANumber : Expr() </span><br><span class="line"></span><br><span class="line"><span class="comment">// 此时用于when的时候就不需要else语句了</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">eval</span><span class="params">(expr: <span class="type">Expr</span>)</span></span>: <span class="built_in">Double</span> = <span class="keyword">when</span>(expr) {</span><br><span class="line"> <span class="keyword">is</span> Const -> expr.number</span><br><span class="line"> <span class="keyword">is</span> Sum -> eval(expr.e1) + eval(expr.e2)</span><br><span class="line"> NotANumber -> <span class="built_in">Double</span>.NaN</span><br><span class="line"> <span class="comment">// 不再需要 `else` 子句,因为我们已经覆盖了所有的情况</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="泛型(通配符不是那么容易理解)"><a href="#泛型(通配符不是那么容易理解)" class="headerlink" title="泛型(通配符不是那么容易理解)"></a>泛型(通配符不是那么容易理解)</h3><blockquote>
<p>Java版本解析</p>
</blockquote>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Java</span></span><br><span class="line"><span class="comment">// List<? extends Number> test的通配符声明,下面赋值是合法的</span></span><br><span class="line">List<? extends Number> test = new ArrayList<? extends Number>();</span><br><span class="line">List<? extends Number> test = new ArrayList<? extends Integer>();</span><br><span class="line">List<? extends Number> test = new ArrayList<? extends <span class="built_in">Double</span>>();</span><br><span class="line"></span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment">读取操作通过以上给定的赋值语句,你一定能从test列表中读取到的元素的类型是什么呢?你可以读取到Number,因为以上的列表要么包含Number元素,要么包含Number的类元素。</span></span><br><span class="line"><span class="comment">你不能保证读取到Integer,因为test可能指向的是List<Double>。</span></span><br><span class="line"><span class="comment">你不能保证读取到Double,因为test可能指向的是List<Integer>。</span></span><br><span class="line"><span class="comment">写入操作过以上给定的赋值语句,你能把一个什么类型的元素合法地插入到test中呢?</span></span><br><span class="line"><span class="comment">你不能插入一个Integer元素,因为test可能指向List<Double>。</span></span><br><span class="line"><span class="comment">你不能插入一个Double元素,因为test可能指向List<Integer>。</span></span><br><span class="line"><span class="comment">你不能插入一个Number元素,因为test可能指向List<Integer>。</span></span><br><span class="line"><span class="comment">你不能往List<? extends T>中插入任何类型的对象,因为你不能保证列表实际指向的类型是什么,你并不能保证列表中实际存储什么类型的对象。唯一可以保证的是,你可以从中读取到T或者T的子类。</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// List<? super Integer> test的通配符声明,下面赋值是合法的</span></span><br><span class="line">List<? <span class="keyword">super</span> Integer> test = new ArrayList<Integer>();</span><br><span class="line">List<? <span class="keyword">super</span> Integer> test = new ArrayList<Number>();</span><br><span class="line">List<? <span class="keyword">super</span> Integer> test = new ArrayList<Object>();</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">读取操作通过以上给定的赋值语句,你一定能从test列表中读取到的元素的类型是什么呢?</span></span><br><span class="line"><span class="comment">你不能保证读取到Integer,因为test可能指向List<Number>或者List<Object>。</span></span><br><span class="line"><span class="comment">你不能保证读取到Number,因为test可能指向List<Object>。</span></span><br><span class="line"><span class="comment">唯一可以保证的是,你可以读取到Object或者Object子类的对象(你并不知道具体的子类是什么)。</span></span><br><span class="line"><span class="comment">写入操作通过以上给定的赋值语句,你能把一个什么类型的元素合法地插入到foo3中呢?你可以插入Integer对象,因为上述声明的列表都支持Integer。</span></span><br><span class="line"><span class="comment">你可以插入Integer的子类的对象,因为Integer的子类同时也是Integer,原因同上。</span></span><br><span class="line"><span class="comment">你不能插入Double对象,因为foo3可能指向ArrayList<Integer>。</span></span><br><span class="line"><span class="comment">你不能插入Number对象,因为foo3可能指向ArrayList<Integer>。</span></span><br><span class="line"><span class="comment">你不能插入Object对象,因为foo3可能指向ArrayList<Integer>。</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>Kotlin</p>
</blockquote>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Java</span></span><br><span class="line"><span class="class"><span class="keyword">interface</span> <span class="title">Source</span><<span class="type">T</span>> </span>{</span><br><span class="line"> T nextT();</span><br><span class="line">}</span><br><span class="line"><span class="comment">// Java</span></span><br><span class="line">void demo(Source<String> strs) {</span><br><span class="line"> Source<Object> objects = strs; <span class="comment">// !!!在 Java 中不允许</span></span><br><span class="line"> <span class="comment">// ……</span></span><br><span class="line">}</span><br><span class="line"><span class="comment">// 关键字 out</span></span><br><span class="line"><span class="comment">// 声明处型变</span></span><br><span class="line"><span class="comment">// 标注类型参数 T 来确保它仅返回(生产),并从不被消费</span></span><br><span class="line"><span class="class"><span class="keyword">interface</span> <span class="title">Source</span><<span class="type">out T</span>> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">nextT</span><span class="params">()</span></span>: T</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">demo</span><span class="params">(strs: <span class="type">Source</span><<span class="type">String</span>>)</span></span> {</span><br><span class="line"> <span class="keyword">val</span> objects: Source<Any> = strs <span class="comment">// 这个没问题,因为 T 是一个 out-参数</span></span><br><span class="line"> <span class="comment">// ……</span></span><br><span class="line">}</span><br><span class="line"><span class="comment">// 关键字 in</span></span><br><span class="line"><span class="comment">// 使得一个类型参数逆变:只可以被消费而不可以被生产</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 类型投影</span></span><br></pre></td></tr></table></figure>
<h3 id="嵌套类"><a href="#嵌套类" class="headerlink" title="嵌套类"></a>嵌套类</h3><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 嵌套类</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Outer</span> </span>{</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">val</span> bar: <span class="built_in">Int</span> = <span class="number">1</span></span><br><span class="line"> <span class="class"><span class="keyword">class</span> <span class="title">Nested</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">foo</span><span class="params">()</span></span> = <span class="number">2</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">val</span> demo = Outer.Nested().foo() <span class="comment">// == 2</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 内部类</span></span><br><span class="line"><span class="comment">// 标记为 inner 的嵌套类能够访问其外部类的成员。内部类会带有一个对外部类的对象的引用</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Outer</span> </span>{</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">val</span> bar: <span class="built_in">Int</span> = <span class="number">1</span></span><br><span class="line"> <span class="keyword">inner</span> <span class="class"><span class="keyword">class</span> <span class="title">Inner</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">foo</span><span class="params">()</span></span> = bar</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">val</span> demo = Outer().Inner().foo() <span class="comment">// == 1</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 匿名内部类</span></span><br><span class="line">window.addMouseListener(<span class="keyword">object</span> : MouseAdapter() {</span><br><span class="line"></span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">mouseClicked</span><span class="params">(e: <span class="type">MouseEvent</span>)</span></span> { …… }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">override</span> <span class="function"><span class="keyword">fun</span> <span class="title">mouseEntered</span><span class="params">(e: <span class="type">MouseEvent</span>)</span></span> { …… }</span><br><span class="line">})</span><br></pre></td></tr></table></figure>
<h3 id="枚举类"><a href="#枚举类" class="headerlink" title="枚举类"></a>枚举类</h3><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 常用枚举</span></span><br><span class="line"><span class="keyword">enum</span> <span class="class"><span class="keyword">class</span> <span class="title">Direction</span> </span>{</span><br><span class="line"> NORTH, SOUTH, WEST, EAST</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 初始化枚举</span></span><br><span class="line"><span class="keyword">enum</span> <span class="class"><span class="keyword">class</span> <span class="title">Color</span></span>(<span class="keyword">val</span> rgb: <span class="built_in">Int</span>) {</span><br><span class="line"> RED(<span class="number">0xFF0000</span>),</span><br><span class="line"> GREEN(<span class="number">0x00FF00</span>),</span><br><span class="line"> BLUE(<span class="number">0x0000FF</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="对象"><a href="#对象" class="headerlink" title="对象"></a>对象</h3><blockquote>
<p>有时候,我们需要创建一个对某个类做了轻微改动的类的对象,而不用为之显式声明新的子类。 Kotlin 用<em>对象表达式</em>和<em>对象声明</em>处理这种情况</p>
</blockquote>
<blockquote>
<p>对象表达式</p>
</blockquote>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 简单的对象表达式</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">foo</span><span class="params">()</span></span> {</span><br><span class="line"> <span class="keyword">val</span> adHoc = <span class="keyword">object</span> {</span><br><span class="line"> <span class="keyword">var</span> x: <span class="built_in">Int</span> = <span class="number">0</span></span><br><span class="line"> <span class="keyword">var</span> y: <span class="built_in">Int</span> = <span class="number">0</span></span><br><span class="line"> }</span><br><span class="line"> print(adHoc.x + adHoc.y)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 匿名对象可以用作只在本地和私有作用域中声明的类型。如果你使用匿名对象作为公有函数的返回类型或者用作公有属性的类型,那么该函数或属性的实际类型会是匿名对象声明的超类型,如果你没有声明任何超类型,就会是 Any。在匿名对象中添加的成员将无法访问</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">C</span> </span>{</span><br><span class="line"> <span class="comment">// 私有函数,所以其返回类型是匿名对象类型</span></span><br><span class="line"> <span class="keyword">private</span> <span class="function"><span class="keyword">fun</span> <span class="title">foo</span><span class="params">()</span></span> = <span class="keyword">object</span> {</span><br><span class="line"> <span class="keyword">val</span> x: String = <span class="string">"x"</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 公有函数,所以其返回类型是 Any</span></span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">publicFoo</span><span class="params">()</span></span> = <span class="keyword">object</span> {</span><br><span class="line"> <span class="keyword">val</span> x: String = <span class="string">"x"</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">bar</span><span class="params">()</span></span> {</span><br><span class="line"> <span class="keyword">val</span> x1 = foo().x <span class="comment">// 没问题</span></span><br><span class="line"> <span class="keyword">val</span> x2 = publicFoo().x <span class="comment">// 错误:未能解析的引用“x”</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<blockquote>
<p>对象声明</p>
</blockquote>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 常见于单例模式</span></span><br><span class="line"><span class="comment">// 对象声明。总是在 object 关键字后跟一个名称。 就像变量声明一样,对象声明不是一个表达式,不能用在赋值语句的右边</span></span><br><span class="line"><span class="keyword">object</span> DataProviderManager {</span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">registerDataProvider</span><span class="params">(provider: <span class="type">DataProvider</span>)</span></span> {</span><br><span class="line"> <span class="comment">// ……</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">val</span> allDataProviders: Collection<DataProvider></span><br><span class="line"> <span class="keyword">get</span>() = <span class="comment">// ……</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<blockquote>
<p>伴生对象 - 有点像Java的静态成员,但是运行时仍然是真实对象的实例成员,如果真的需要用类似Java的静态,则可以使用@JvmStatic注解修饰</p>
</blockquote>
<figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 关键字 companion</span></span><br><span class="line"><span class="comment">// 类内部用 companion 标记的对象</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyClass</span> </span>{</span><br><span class="line"> <span class="keyword">companion</span> <span class="keyword">object</span> Factory {</span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">create</span><span class="params">()</span></span>: MyClass = MyClass()</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="函数"><a href="#函数" class="headerlink" title="函数"></a>函数</h2><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 不带参数</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> 函数名<span class="params">()</span></span>{</span><br><span class="line"> </span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 返回无意义的值</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> 函数名<span class="params">()</span></span>:<span class="built_in">Unit</span>{</span><br><span class="line"> </span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 带参数和返回值</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> 函数名<span class="params">(a:<span class="type">Int</span>, b:<span class="type">Int</span>)</span></span>: <span class="built_in">Int</span>{</span><br><span class="line"> <span class="keyword">return</span> a + b</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 简化(单表达式函数)</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> 函数名<span class="params">(a:<span class="type">Int</span>, b:<span class="type">Int</span>)</span></span> = a + b</span><br><span class="line"></span><br><span class="line"><span class="comment">// 函数带有默认值</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> 函数名<span class="params">(number:<span class="type">Int</span> = <span class="number">1</span>)</span></span>{}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 函数前参数带有默认值,后参数不带,该默认值则需要使用具名参数来调用函数,否则编译器会报错</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> 函数名<span class="params">(number:<span class="type">Int</span> = <span class="number">1</span>, count:<span class="type">Int</span>)</span></span>{}</span><br><span class="line">函数名(count=<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 函数前参数带有默认值,后面一个参数是lambda表达式,则可以使用具名参数来调用,或者括号外传入</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> 函数名<span class="params">(number:<span class="type">Int</span> = <span class="number">1</span>, qux: () -> <span class="type">Unit</span>)</span></span>{}</span><br><span class="line">函数名(qux = {})</span><br><span class="line">函数名{}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 函数-可变数量的参数(通常是最后一个参数)</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="type"><T></span> <span class="title">asList</span><span class="params">(<span class="keyword">vararg</span> ts: <span class="type">T</span>)</span></span>:List<T>{</span><br><span class="line"> <span class="keyword">for</span>(t <span class="keyword">in</span> ts){</span><br><span class="line"> </span><br><span class="line"> } </span><br><span class="line">}</span><br><span class="line">asList(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 函数-中缀表示法,必须是成员函数或者扩展函数,必须只有一个参数,参数不能是可变数量参数并且不能有默认值</span></span><br><span class="line"><span class="keyword">infix</span> <span class="function"><span class="keyword">fun</span> <span class="built_in">Int</span>.<span class="title">shl</span><span class="params">(x:<span class="type">Int</span>)</span></span>:<span class="built_in">Int</span>{}</span><br><span class="line"><span class="comment">// 中缀表示法</span></span><br><span class="line"><span class="number">1</span> shl <span class="number">2</span></span><br><span class="line"><span class="comment">// 普通写法</span></span><br><span class="line"><span class="number">1.</span>shl(<span class="number">2</span>)</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h3 id="函数作用域"><a href="#函数作用域" class="headerlink" title="函数作用域"></a>函数作用域</h3><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Kotlin函数可以在文件顶部声明(顶层函数)</span></span><br><span class="line"><span class="comment">// </span></span><br><span class="line"><span class="comment">// 局部函数 - 即一个函数在另一个函数里面</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">a</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">b</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="comment">// 可以访问外部函数的局部变量</span></span><br><span class="line"> }</span><br><span class="line"> b();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 成员函数 - 类或者对象内部定义的函数</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">A</span></span>{</span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">afun</span><span class="params">()</span></span>{</span><br><span class="line"> </span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 泛型函数</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="type"><T></span> <span class="title">singletonList</span><span class="params">(item: <span class="type">T</span>)</span></span>:List<T>{}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 内联函数</span></span><br><span class="line"><span class="comment">// inline, noinline</span></span><br><span class="line"><span class="keyword">inline</span> <span class="function"><span class="keyword">fun</span> <span class="type"><T></span> <span class="title">lock</span><span class="params">(lock: <span class="type">Lock</span>, body:() -> <span class="type">T</span>)</span></span>:T{}</span><br><span class="line"><span class="comment">// 如果只希望内联一部分</span></span><br><span class="line"><span class="keyword">inline</span> <span class="function"><span class="keyword">fun</span> <span class="title">foo</span><span class="params">(inlined: () -> <span class="type">Unit</span>, <span class="keyword">noinline</span> notInlined: () -> <span class="type">Unit</span>)</span></span> {}</span><br></pre></td></tr></table></figure>
<h3 id="非局部返回"><a href="#非局部返回" class="headerlink" title="非局部返回"></a>非局部返回</h3><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 非局部返回 - 位于lambda表达式中,但退出包含它的函数</span></span><br><span class="line"><span class="comment">// 在正常使用函数中,如果要退出一个lambda表达式则需要一个标签</span></span><br><span class="line"><span class="comment">// 如果这个表达式传给的函数是内联的,则可以return</span></span><br></pre></td></tr></table></figure>
<h2 id="字符串模版"><a href="#字符串模版" class="headerlink" title="字符串模版"></a>字符串模版</h2><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// $关键字</span></span><br><span class="line"><span class="keyword">var</span> a = <span class="number">1</span></span><br><span class="line"><span class="keyword">val</span> s1 = <span class="string">"a is <span class="variable">$a</span>"</span></span><br><span class="line"></span><br><span class="line">a = <span class="number">2</span></span><br><span class="line"><span class="keyword">val</span> s2 = <span class="string">"<span class="subst">${s1.replace(<span class="string">"is"</span>, <span class="string">"was"</span>)}</span>, but now is <span class="variable">$a</span>"</span></span><br></pre></td></tr></table></figure>
<h2 id="空值和null检测"><a href="#空值和null检测" class="headerlink" title="空值和null检测"></a>空值和null检测</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">// ?关键字 对象可为null,需要添加?</span><br><span class="line"></span><br><span class="line">// 返回值可为null,需要在返回值类型后添加?</span><br><span class="line">fun parseInt(str:String):Int?{</span><br><span class="line"> </span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="类型检测与自动变换类型"><a href="#类型检测与自动变换类型" class="headerlink" title="类型检测与自动变换类型"></a>类型检测与自动变换类型</h2><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// is关键字</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">getStringLength</span><span class="params">(obj:<span class="type">Any</span>)</span></span>:<span class="built_in">Int</span>?{</span><br><span class="line"> <span class="keyword">if</span>(obj <span class="keyword">is</span> String){</span><br><span class="line"> <span class="keyword">return</span> obj.length</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">null</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="使用区间"><a href="#使用区间" class="headerlink" title="使用区间"></a>使用区间</h2><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// ..关键字</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// in 判断是否在区间内</span></span><br><span class="line"><span class="keyword">val</span> x = <span class="number">10</span></span><br><span class="line"><span class="keyword">val</span> y = <span class="number">9</span></span><br><span class="line"><span class="keyword">if</span>(x <span class="keyword">in</span> <span class="number">1.</span>.y+<span class="number">1</span>){</span><br><span class="line"> println(<span class="string">"yes"</span>)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 区间迭代</span></span><br><span class="line"><span class="keyword">for</span>(x <span class="keyword">in</span> <span class="number">1.</span><span class="number">.5</span>){</span><br><span class="line"> print(x)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span>(x <span class="keyword">in</span> <span class="number">1</span> until <span class="number">5</span>){</span><br><span class="line"> print(x)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 数列迭代</span></span><br><span class="line"><span class="keyword">for</span>(x <span class="keyword">in</span> <span class="number">1.</span><span class="number">.10</span> step <span class="number">2</span>){</span><br><span class="line"> print(x)</span><br><span class="line">}</span><br><span class="line"><span class="keyword">for</span>(x <span class="keyword">in</span> <span class="number">9</span> downTo <span class="number">0</span> step <span class="number">3</span>){</span><br><span class="line"> print(x)</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="集合"><a href="#集合" class="headerlink" title="集合"></a>集合</h2><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// List</span></span><br><span class="line"><span class="comment">// listOf,mutableListOf</span></span><br><span class="line"><span class="keyword">val</span> people = listOf(Person(<span class="string">"Adam"</span>, <span class="number">20</span>), bob, bob)</span><br><span class="line"></span><br><span class="line"><span class="comment">// Set</span></span><br><span class="line"><span class="comment">// setOf,mutableSetOf</span></span><br><span class="line"><span class="keyword">val</span> numbers = setOf(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// Map</span></span><br><span class="line"><span class="comment">// mapOf,mutableMapOf</span></span><br><span class="line"><span class="comment">// to符号创建了一个短时存活的Pair对象</span></span><br><span class="line"><span class="comment">// 最好使用别的方法初始化,比如使用apply</span></span><br><span class="line"><span class="keyword">val</span> numbersMap = mapOf(<span class="string">"key1"</span> to <span class="number">1</span>, <span class="string">"key2"</span> to <span class="number">2</span>, <span class="string">"key3"</span> to <span class="number">3</span>, <span class="string">"key4"</span> to <span class="number">1</span>) </span><br><span class="line"><span class="keyword">val</span> numbersMap = mutableMapOf(<span class="string">"one"</span> to <span class="number">1</span>, <span class="string">"two"</span> to <span class="number">2</span>)</span><br><span class="line"><span class="keyword">val</span> numbersMap = mutableMapOf<String, String>().apply { <span class="keyword">this</span>[<span class="string">"one"</span>] = <span class="string">"1"</span>; <span class="keyword">this</span>[<span class="string">"two"</span>] = <span class="string">"2"</span> }</span><br><span class="line"></span><br><span class="line"><span class="comment">// 集合复制</span></span><br><span class="line"><span class="comment">// toList()、toMutableList()、toSet()</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 调用集合操作创建新集合</span></span><br><span class="line"><span class="comment">// filter</span></span><br><span class="line"><span class="comment">// map</span></span><br><span class="line"><span class="comment">// mapIndexed</span></span><br><span class="line"><span class="comment">// associateWith</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 序列</span></span><br><span class="line"><span class="comment">// </span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 迭代集合</span></span><br><span class="line"><span class="keyword">for</span>(item <span class="keyword">in</span> items){</span><br><span class="line"> print(item)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 判断是否包含</span></span><br><span class="line"><span class="keyword">when</span>{</span><br><span class="line"> <span class="string">"orange"</span> <span class="keyword">in</span> items -> print(<span class="string">"orange"</span>)</span><br><span class="line"> <span class="string">"apple"</span> <span class="keyword">in</span> items -> print(<span class="string">"apple"</span>) </span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 过滤集合(filter map)</span></span><br><span class="line"><span class="keyword">var</span> items = listOf(<span class="string">"apple"</span>, <span class="string">"banana"</span>, <span class="string">"orange"</span>)</span><br><span class="line">items</span><br><span class="line"> .filter{ it.startsWith(<span class="string">"A"</span>) }</span><br><span class="line"> .sortedBy{ it }</span><br><span class="line"> .map{ it.toUpperCase() }</span><br><span class="line"> .forEach{ print(it) }</span><br></pre></td></tr></table></figure>
<h1 id="语法习惯-适用于简化代码"><a href="#语法习惯-适用于简化代码" class="headerlink" title="语法习惯(适用于简化代码)"></a>语法习惯(适用于简化代码)</h1><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 创建带有- getters/equals/hashCode/toString/copy功能的类</span></span><br><span class="line"><span class="keyword">data</span> <span class="class"><span class="keyword">class</span> <span class="title">Customer</span></span>(<span class="keyword">var</span> name:String, <span class="keyword">val</span> email:String)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 函数带有默认参数</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">foo</span><span class="params">(a:<span class="type">Int</span> = <span class="number">0</span>, b:<span class="type">String</span> = <span class="string">""</span>)</span></span>{}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 过滤list</span></span><br><span class="line"><span class="keyword">val</span> positives = list.filter{ x -> x > <span class="number">0</span> }</span><br><span class="line"><span class="keyword">val</span> positives = list.filter{ it > <span class="number">0</span> }</span><br><span class="line"></span><br><span class="line"><span class="comment">// 检查元素是否在集合中</span></span><br><span class="line"><span class="keyword">if</span>(<span class="string">"xx"</span> <span class="keyword">in</span> list){}</span><br><span class="line"><span class="keyword">if</span>(<span class="string">"xx"</span> !<span class="keyword">in</span> list){}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 字符串内插</span></span><br><span class="line">println(<span class="string">"Name <span class="variable">$name</span>"</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 类型判断</span></span><br><span class="line"><span class="keyword">when</span>(x){</span><br><span class="line"> <span class="keyword">is</span> Foo</span><br><span class="line"> <span class="keyword">is</span> Bar</span><br><span class="line"> <span class="keyword">else</span> </span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 遍历map</span></span><br><span class="line"><span class="keyword">for</span>((k,v) <span class="keyword">in</span> map){</span><br><span class="line"> println(<span class="string">"<span class="variable">$k</span> -> <span class="variable">$v</span>"</span>)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用区间</span></span><br><span class="line"><span class="keyword">for</span>(i <span class="keyword">in</span> <span class="number">1.</span><span class="number">.100</span>){}</span><br><span class="line"><span class="keyword">for</span>(i <span class="keyword">in</span> <span class="number">1</span> until <span class="number">100</span>){}</span><br><span class="line"><span class="keyword">for</span>(x <span class="keyword">in</span> <span class="number">2.</span><span class="number">.10</span> step <span class="number">2</span>){}</span><br><span class="line"><span class="keyword">for</span>(x <span class="keyword">in</span> <span class="number">10</span> downTo <span class="number">1</span>){}</span><br><span class="line"><span class="keyword">if</span>(x <span class="keyword">in</span> <span class="number">1.</span><span class="number">.10</span>){}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 只读list</span></span><br><span class="line"><span class="keyword">val</span> list = listOf(<span class="string">"a"</span>, <span class="string">"b"</span>, <span class="string">"c"</span>)</span><br><span class="line"><span class="comment">// 只读map</span></span><br><span class="line"><span class="keyword">val</span> map = mapOf(<span class="string">"a"</span> to <span class="number">1</span>, <span class="string">"b"</span> to <span class="number">2</span>, <span class="string">"c"</span> to <span class="number">3</span>)</span><br><span class="line"><span class="comment">// 访问map</span></span><br><span class="line">println(map[<span class="string">"key"</span>])</span><br><span class="line">map[<span class="string">"key"</span>] = value</span><br><span class="line"></span><br><span class="line"><span class="comment">// 延迟属性</span></span><br><span class="line"><span class="keyword">val</span> p: String <span class="keyword">by</span> lazy{}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 扩展函数</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> String.<span class="title">spaceToCamelCase</span><span class="params">()</span></span>{}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建单例</span></span><br><span class="line"><span class="keyword">object</span> Resource{</span><br><span class="line"> <span class="keyword">val</span> name = <span class="string">"Name"</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// if not null and else 缩写</span></span><br><span class="line"><span class="keyword">val</span> files = File(<span class="string">"Test"</span>).listFiles()</span><br><span class="line">print(files?.size ?: <span class="string">"empty"</span>)</span><br><span class="line"><span class="comment">// if null 执行一个语句</span></span><br><span class="line">files?.size ?: <span class="keyword">throw</span> IllegalStateException()</span><br><span class="line"></span><br><span class="line"><span class="comment">// 在可能会空的集合中取第一个元素</span></span><br><span class="line"><span class="keyword">val</span> emails = xx</span><br><span class="line"><span class="keyword">val</span> mainEmail = emails.firstOrNull() ?: <span class="string">""</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// if not null 执行代码</span></span><br><span class="line"><span class="keyword">val</span> value = <span class="string">"xxx"</span></span><br><span class="line">value?.let{</span><br><span class="line"> </span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 映射可空值</span></span><br><span class="line"><span class="keyword">val</span> value = <span class="string">"xxx"</span></span><br><span class="line"><span class="keyword">val</span> mapped = value?.let{ transformValue(it) } ?: defaultValue</span><br><span class="line"></span><br><span class="line"><span class="comment">// 返回when表达式</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">transform</span><span class="params">(color:<span class="type">String</span>)</span></span>:<span class="built_in">Int</span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">when</span>(colot){</span><br><span class="line"> <span class="string">"Red"</span> -> <span class="number">0</span></span><br><span class="line"> <span class="string">"Green"</span> -> <span class="number">1</span></span><br><span class="line"> <span class="string">"Blue"</span> -> <span class="number">2</span></span><br><span class="line"> <span class="keyword">else</span> <span class="number">0</span> -> <span class="keyword">throw</span> IllegalArgumentException()</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// try catch表达式</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">test</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="keyword">val</span> result = <span class="keyword">try</span>{</span><br><span class="line"> count()</span><br><span class="line"> }<span class="keyword">catch</span>(e:Exception){</span><br><span class="line"> </span><br><span class="line"> }</span><br><span class="line"> <span class="comment">// 使用result</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// if 表达式</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">foo</span><span class="params">(param: <span class="type">Int</span>)</span></span>{</span><br><span class="line"> <span class="keyword">var</span> result = <span class="keyword">if</span>(param == <span class="number">1</span>){</span><br><span class="line"> </span><br><span class="line"> }<span class="keyword">else</span> <span class="keyword">if</span>(param == <span class="number">2</span>){</span><br><span class="line"> </span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> </span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 单表达式函数</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">test</span><span class="params">()</span></span> = <span class="number">12</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 函数简化</span></span><br><span class="line"><span class="function"><span class="keyword">fun</span> <span class="title">transform</span><span class="params">(color:<span class="type">String</span>)</span></span>:<span class="built_in">Int</span> = <span class="keyword">when</span>(color){</span><br><span class="line"> <span class="string">"Red"</span> -> <span class="number">0</span></span><br><span class="line"> <span class="string">"Green"</span> -> <span class="number">1</span> </span><br><span class="line"> <span class="string">"Blue"</span> -> <span class="number">2</span></span><br><span class="line"> <span class="keyword">else</span> -> <span class="keyword">throw</span> IllegalArgumentException()</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 对一个对象实例调用多个方法</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">A</span></span>{</span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">test1</span><span class="params">()</span></span></span><br><span class="line"> <span class="function"><span class="keyword">fun</span> <span class="title">test2</span><span class="params">()</span></span></span><br><span class="line">}</span><br><span class="line"><span class="keyword">val</span> a = A()</span><br><span class="line">with(a){</span><br><span class="line"> test1()</span><br><span class="line"> test2()</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 配置对象的属性</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">A</span></span>{</span><br><span class="line"> <span class="keyword">var</span> num = <span class="number">0</span></span><br><span class="line"> <span class="keyword">var</span> count = <span class="number">0</span></span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> a = A().apply{</span><br><span class="line"> num = <span class="number">1</span></span><br><span class="line"> count = <span class="number">6</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// Java 7 try with resources</span></span><br><span class="line"><span class="keyword">val</span> stream = Files.newInputStream(Paths.<span class="keyword">get</span>(<span class="string">"/some/file.txt"</span>))</span><br><span class="line">stream.buffered().reader().use{ reader -> </span><br><span class="line"> println(reader.readText())</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
</div>
<script>
window.addEventListener('tabs:register', () => {
let { activeClass } = CONFIG.comments;
if (CONFIG.comments.storage) {
activeClass = localStorage.getItem('comments_active') || activeClass;
}
if (activeClass) {
let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
if (activeTab) {
activeTab.click();
}
}
});
if (CONFIG.comments.storage) {
window.addEventListener('tabs:click', event => {
if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
let commentClass = event.target.classList[1];
localStorage.setItem('comments_active', commentClass);
});
}
</script>
</div>
<div class="toggle sidebar-toggle">
<span class="toggle-line toggle-line-first"></span>
<span class="toggle-line toggle-line-middle"></span>
<span class="toggle-line toggle-line-last"></span>
</div>
<aside class="sidebar">
<div class="sidebar-inner">
<ul class="sidebar-nav motion-element">
<li class="sidebar-nav-toc">
文章目录
</li>
<li class="sidebar-nav-overview">
站点概览