-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathUI总结.html
843 lines (785 loc) · 221 KB
/
UI总结.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
<html>
<head>
<title>Evernote Export</title>
<basefont face="微软雅黑" size="2" />
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="exporter-version" content="YXBJ Windows/602051 (zh-CN, DDL); Windows/10.0.0 (Win64); EDAMVersion=V2;"/>
<meta name="content-class" content="yinxiang.markdown"/>
<style>
body, td {
font-family: 微软雅黑;
font-size: 10pt;
}
</style>
</head>
<body>
<a name="624"/>
<div><span><div style="font-size: 14px; margin: 0; padding: 0; width: 100%;"><h1 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 41px; border-bottom: 3px double #999; color: #000; margin-top: 14px;">高级UI</h1>
<h3 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 27px; color: #333;">系统ViewGroup原理解析</h3>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">常见的布局容器: FrameLayout, LinearLayout,RelativeLayoout,GridLayout<br/>
后起之秀:ConstraintLayout,CoordinateLayout</p>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">Linearlayout</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #9b9b9b; line-height: 160%; box-sizing: content-box;">@Override</span>
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">protected</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">void</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">onMeasure</span><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> widthMeasureSpec, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> heightMeasureSpec)</span> </span>{
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (mOrientation == VERTICAL) {
measureVertical(widthMeasureSpec, heightMeasureSpec);
} <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> {
measureHorizontal(widthMeasureSpec, heightMeasureSpec);
}
}
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">onMeasure(int widthMeasureSpec, int heightMeasureSpec) 源码如上所示,通过 mOrientation 分别处理垂直和水平两个方向的测量,其中的 mOrientation 变量则是我们在 xml 布局文件中通过 android:orientation="vertical" 或者直接通过 setOrientation(@OrientationMode int orientation) 方法设置的 LinearLayout 文件方向变量</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">我们仅分析垂直方向的测量方法,也就是 measureVertical(int widthMeasureSpec, int heightMeasureSpec)(水平方向的测量方法 measureHorizontal(int widthMeasureSpec, int heightMeasureSpec) 是类似的原理,有兴趣的朋友可以自己分析)</p>
<h6 style="line-height: 160%; box-sizing: content-box; font-size: 13px; color: #333;">初始化变量</h6>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">需要初始化一些类变量 & 声明一些重要的局部变量</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">void</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">measureVertical</span><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> widthMeasureSpec, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> heightMeasureSpec)</span> </span>{
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//第一阶段,主要是一些变量的初始化</span>
mTotalLength = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>;<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 所有 childView 的高度和 + 本身的 padding,注意:它和 LinearLayout 本身的高度是不同的</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> maxWidth = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>;<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 所有 childView 中宽度的最大值</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> childState = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> alternativeMaxWidth = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>;<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 所有 layout_weight <= 0 的 childView 中宽度的最大值</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> weightedMaxWidth = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>;<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 所有 layout_weight >0 的 childView 中宽度的最大值</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">boolean</span> allFillParent = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">true</span>;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">float</span> totalWeight = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>;<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 所有 childView 的 weight 之和</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> count = getVirtualChildCount();
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> widthMode = MeasureSpec.getMode(widthMeasureSpec);
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> heightMode = MeasureSpec.getMode(heightMeasureSpec);
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">boolean</span> matchWidth = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">false</span>;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">boolean</span> skippedMeasure = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">false</span>;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> baselineChildIndex = mBaselineAlignedChildIndex;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">boolean</span> useLargestChild = mUseLargestChild;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> largestChildHeight = Integer.MIN_VALUE;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> consumedExcessSpace = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> nonSkippedChildCount = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>;
...
}
</code></pre>
<h6 style="line-height: 160%; box-sizing: content-box; font-size: 13px; color: #333;">第一次测量</h6>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">在测量第一阶段会计算那些没有设置 weight 的 childView 的高度、计算 mTotleLength,并且计算三个宽度相关的变量的值</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">void</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">measureVertical</span><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> widthMeasureSpec, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> heightMeasureSpec)</span> </span>{
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//第二阶段,第一次测量,接上面代码</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// See how tall everyone is. Also remember max width.</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//第一遍循环,看看每个childview的高度,并且记录最大宽度</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">for</span> (<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> i = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>; i < count; ++i) {<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//一层for循环</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> View child = getVirtualChildAt(i);<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//获取到每一个childview</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (child == <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">null</span>) {
mTotalLength += measureNullChild(i);
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">continue</span>;
}
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (child.getVisibility() == View.GONE) {
i += getChildrenSkipCount(child, i);
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">continue</span>;
}
nonSkippedChildCount++;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (hasDividerBeforeChildAt(i)) {
mTotalLength += mDividerHeight;
}
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> LayoutParams lp = (LayoutParams) child.getLayoutParams();
totalWeight += lp.weight;<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//计算总权重</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">boolean</span> useExcessSpace = lp.height == <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span> && lp.weight > <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>;<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//使用了权重才会满足</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 我们都知道,测量模式有三种:</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// * UNSPECIFIED:父控件对子控件无约束</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// * Exactly:父控件对子控件强约束,子控件永远在父控件边界内,越界则裁剪。如果要记忆的话,可以记忆为有对应的具体数值或者是Match_parent</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// * AT_Most:子控件为wrap_content的时候,测量值为AT</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (heightMode == MeasureSpec.EXACTLY && useExcessSpace) {<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//确切高度,且height=0 权重>0</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Optimization: don't bother measuring children who are only</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// laid out using excess space. These views will get measured</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// later if we have space to distribute.</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//先跳过测量模式为EXACTLY并且需要权重计算的childview </span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 在后面第三个 for 循环重新计算此 childView 大小</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> totalLength = mTotalLength;
mTotalLength = Math.max(totalLength, totalLength + lp.topMargin + lp.bottomMargin);
skippedMeasure = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">true</span>;<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//后面跳过Measure</span>
} <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> {<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//高度不是确定可能是AT_MOST/UNSPECIFIED</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (useExcessSpace) {
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// The heightMode is either UNSPECIFIED or AT_MOST, and</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// this child is only laid out using excess space. Measure</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// using WRAP_CONTENT so that we can find out the view's</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// optimal height. We'll restore the original height of 0</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// after measurement.</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//把使用权重的childview的高度设置为wrap_content</span>
lp.height = LayoutParams.WRAP_CONTENT;
}
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Determine how big this child would like to be. If this or</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// previous children have given a weight, then we allow it to</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// use all available space (and we will shrink things later</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// if needed).</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//这是非常重要的一个方法,将会决定每个 childView 的大小</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//如果此 childView 及在此 childView 之前的 childView 中使用了 weight 属性,</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 我们允许此 childView 使用所有的空间(后续如果需要,再做调整)</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> usedHeight = totalWeight == <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span> ? mTotalLength : <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>;
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//调用viewgroup中方法测量子view</span>
measureChildBeforeLayout(child, i, widthMeasureSpec, <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>,
heightMeasureSpec, usedHeight);
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 得到测量之后的 childView 的 childHeight</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> childHeight = child.getMeasuredHeight();
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (useExcessSpace) {
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Restore the original height and record how much space</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// we've allocated to excess-only children so that we can</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// match the behavior of EXACTLY measurement.</span>
lp.height = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>;
consumedExcessSpace += childHeight;
}
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 将此 childView 的 childHeight 加入到 mTotalLength 中</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 并加上 childView 的 topMargin 和 bottomMargin </span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// getNextLocationOffset 方法返回 0,方便以后扩展使用</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> totalLength = mTotalLength;
mTotalLength = Math.max(totalLength, totalLength + childHeight + lp.topMargin +
lp.bottomMargin + getNextLocationOffset(child));
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (useLargestChild) {
largestChildHeight = Math.max(childHeight, largestChildHeight);<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//记录最大子view高度</span>
}
}
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 下面两个 if 判断都和 `android:baselineAlignedChildIndex` 属性有关,这里不展开分析</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">/**
* If applicable, compute the additional offset to the child's baseline
* we'll need later when asked {<span style="color: #608b4e; line-height: 160%; box-sizing: content-box;">@link</span> #getBaseline}.
*/</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> ((baselineChildIndex >= <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>) && (baselineChildIndex == i + <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>)) {
mBaselineChildTop = mTotalLength;
}
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// if we are trying to use a child index for our baseline, the above</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// book keeping only works if there are no children above it with</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// weight. fail fast to aid the developer.</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (i < baselineChildIndex && lp.weight > <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>) {
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">throw</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> RuntimeException(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">"A child of LinearLayout with index "</span>
+ <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">"less than mBaselineAlignedChildIndex has weight > 0, which "</span>
+ <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">"won't work. Either remove the weight, or don't set "</span>
+ <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">"mBaselineAlignedChildIndex."</span>);
}
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">boolean</span> matchWidthLocally = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">false</span>;<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//该子view是否需要测量宽度</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 所有 widthMode 是 `MeasureSpec.EXACTLY`,不会进入此 if 判断 </span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (widthMode != MeasureSpec.EXACTLY && lp.width == LayoutParams.MATCH_PARENT) {
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// The width of the linear layout will scale, and at least one</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// child said it wanted to match our width. Set a flag</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// indicating that we need to remeasure at least that view when</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// we know our width.</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 当父类(LinearLayout)不是match_parent或者精确值的时候,但子控件却是一个match_parent</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 那么matchWidthLocally和matchWidth置为true</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 意味着这个控件将会占据父类(水平方向)的所有空间</span>
matchWidth = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">true</span>;
matchWidthLocally = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">true</span>;
}
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 计算三个和宽度相关的变量值</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> margin = lp.leftMargin + lp.rightMargin;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> measuredWidth = child.getMeasuredWidth() + margin;
maxWidth = Math.max(maxWidth, measuredWidth);
childState = combineMeasuredStates(childState, child.getMeasuredState());<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//获取子viewmeasure后的state状态</span>
allFillParent = allFillParent && lp.width == LayoutParams.MATCH_PARENT;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (lp.weight > <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>) {
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//需要计算权重的</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">/*
* Widths of weighted Views are bogus if we end up
* remeasuring, so keep them separate.
* alternative 可供选择的
*/</span>
weightedMaxWidth = Math.max(weightedMaxWidth,
matchWidthLocally ? margin : measuredWidth);
} <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> {
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//如果不需要计算权重走这里</span>
alternativeMaxWidth = Math.max(alternativeMaxWidth,
matchWidthLocally ? margin : measuredWidth);
}
i += getChildrenSkipCount(child, i);
}<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//for循环结束</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 如果存在没有跳过的 childView 并且需要绘制 end divider 则需要加上 end 位置的 divider 的高度</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (nonSkippedChildCount > <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span> && hasDividerBeforeChildAt(count)) {
mTotalLength += mDividerHeight;
}
</code></pre>
<h6 style="line-height: 160%; box-sizing: content-box; font-size: 13px; color: #333;">measureChildBeforeLayout()</h6>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">在此方法中将会计算每个 childView 的大小,调用 ViewGroup 的 measureChildWithMargins() 方法计算每个 childView 的大小,在测量垂直方向的 childView 时,有一个非常重要的参数需要注意,即:heightUsed,根据英文注释,heightUsed 是指在垂直方向,已经被 parentView 或者 parentView 的其他 childView 使用了的空间</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">void</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">measureChildBeforeLayout</span><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(View child, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> childIndex,
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> widthMeasureSpec, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> totalWidth, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> heightMeasureSpec,
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> totalHeight)</span> </span>{
measureChildWithMargins(child, widthMeasureSpec, totalWidth,
heightMeasureSpec, totalHeight);
}
</code></pre>
<h6 style="line-height: 160%; box-sizing: content-box; font-size: 13px; color: #333;">第二次测量</h6>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">如果进入这个 if 条件,会进行第二次的 for 循环遍历 childView,重新计算 mTotalLength</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">void</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">measureVertical</span><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> widthMeasureSpec, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> heightMeasureSpec)</span> </span>{
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//接上面代码</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (useLargestChild &&
(heightMode == MeasureSpec.AT_MOST || heightMode == MeasureSpec.UNSPECIFIED)) {
mTotalLength = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>;
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//重新计算总高度:每个非gone的view的高度都按 上次循环记录的最大子view的高度计算,再加上margin</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">for</span> (<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> i = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>; i < count; ++i) {
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> View child = getVirtualChildAt(i);
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (child == <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">null</span>) {
mTotalLength += measureNullChild(i);
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">continue</span>;
}
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (child.getVisibility() == GONE) {
i += getChildrenSkipCount(child, i);
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">continue</span>;
}
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)
child.getLayoutParams();
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Account for negative margins</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> totalLength = mTotalLength;
mTotalLength = Math.max(totalLength, totalLength + largestChildHeight +
lp.topMargin + lp.bottomMargin + getNextLocationOffset(child));
}
}
</code></pre>
<h6 style="line-height: 160%; box-sizing: content-box; font-size: 13px; color: #333;">测量第三阶段</h6>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">针对设置了 android:layout_weight 属性的布局,重新计算 mTotalLength</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">void</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">measureVertical</span><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> widthMeasureSpec, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> heightMeasureSpec)</span> </span>{
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//接上面代码</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Add in our padding</span>
mTotalLength += mPaddingTop + mPaddingBottom;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> heightSize = mTotalLength;
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Check against our minimum height</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 通过 getSuggestedMinimumHeight() 得到建议最小高度,并和计算得到的</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// mTotalLength 比较取最大值</span>
heightSize = Math.max(heightSize, getSuggestedMinimumHeight());
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Reconcile our calculated size with the heightMeasureSpec</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 通过 heightMeasureSpec,调整 heightSize 的大小</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> heightSizeAndState = resolveSizeAndState(heightSize, heightMeasureSpec, <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>);
heightSize = heightSizeAndState & MEASURED_SIZE_MASK;
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Either expand children with weight to take up available space or</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// shrink them if they extend beyond our current bounds. If we skipped</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// measurement on any children, we need to measure them now.</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 重新计算有 weight 属性的 childView 大小,</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 如果还有可用的空间,则扩展 childView,计算其大小</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 如果 childView 超出了 LinearLayout 的边界,则收缩 childView</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> remainingExcess = heightSize - mTotalLength
+ (mAllowInconsistentMeasurement ? <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span> : consumedExcessSpace);
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (skippedMeasure
|| ((sRemeasureWeightedChildren || remainingExcess != <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>) && totalWeight > <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0.0f</span>)) {
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 根据 mWeightSum 计算得到 remainingWeightSum,mWeightSum 是通过 </span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// `android:weightSum` 属性设置的,totalWeight 是通过第一次 for 循环计算得到的</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">float</span> remainingWeightSum = mWeightSum > <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0.0f</span> ? mWeightSum : totalWeight;
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 将 mTotalLength 复位为 0</span>
mTotalLength = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>;
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 权重childview的测量,开始真正的第二次 for 循环遍历每一个 childView,重新测量每一个 childView</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">for</span> (<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> i = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>; i < count; ++i) {
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> View child = getVirtualChildAt(i);
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (child == <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">null</span> || child.getVisibility() == View.GONE) {
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">continue</span>;
}
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> LayoutParams lp = (LayoutParams) child.getLayoutParams();
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">float</span> childWeight = lp.weight
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 如果该 childView 设置了 `weight` 值,则进入 if 语句块</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (childWeight > <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>) {
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 这是设置了 weight 的情况下,最重要的一行代码</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// remainingExcess 剩余高度 * ( childView 的 weight / remainingWeightSum)</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// share 便是此 childView 通过这个公式计算得到的高度, </span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 并重新计算剩余高度 remainingExcess 和剩余权重总和 remainingWeightSum</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> share = (<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span>) (childWeight * remainingExcess / remainingWeightSum);
remainingExcess -= share;
remainingWeightSum -= childWeight;
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 通过下面的 if 条件重新计算,childHeight 是最终 childView 的真正高度</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> childHeight;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (mUseLargestChild && heightMode != MeasureSpec.EXACTLY) {
childHeight = largestChildHeight;
} <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (lp.height == <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span> && (!mAllowInconsistentMeasurement
|| heightMode == MeasureSpec.EXACTLY)) {
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// This child needs to be laid out from scratch using</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// only its share of excess space.</span>
childHeight = share;
} <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> {
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// This child had some intrinsic height to which we</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// need to add its share of excess space.</span>
childHeight = child.getMeasuredHeight() + share;
}
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 计算 childHeightMeasureSpec & childWidthMeasureSpec,并调用 child.measure() 方法</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
Math.max(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>, childHeight), MeasureSpec.EXACTLY);
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin,
lp.width);
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Child may now not fit in vertical dimension.</span>
childState = combineMeasuredStates(childState, child.getMeasuredState()
& (MEASURED_STATE_MASK>>MEASURED_HEIGHT_STATE_SHIFT));
}
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> margin = lp.leftMargin + lp.rightMargin;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> measuredWidth = child.getMeasuredWidth() + margin;
maxWidth = Math.max(maxWidth, measuredWidth);
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">boolean</span> matchWidthLocally = widthMode != MeasureSpec.EXACTLY &&
lp.width == LayoutParams.MATCH_PARENT;
alternativeMaxWidth = Math.max(alternativeMaxWidth,
matchWidthLocally ? margin : measuredWidth);
allFillParent = allFillParent && lp.width == LayoutParams.MATCH_PARENT;
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 考虑 childView.topMargin & childView.bottomMargin,重新计算 mTotalLength</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> totalLength = mTotalLength;
mTotalLength = Math.max(totalLength, totalLength + child.getMeasuredHeight() +
lp.topMargin + lp.bottomMargin + getNextLocationOffset(child));
}
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Add in our padding</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 完成 for 循环之后,加入 LinearLayout 本身的 mPaddingTop & mPaddingBottom</span>
mTotalLength += mPaddingTop + mPaddingBottom;
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// <span style="color: #608b4e; line-height: 160%; box-sizing: content-box;">TODO:</span> Should we recompute the heightSpec based on the new total length?</span>
} <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> {
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 重新计算 alternativeMaxWidth</span>
alternativeMaxWidth = Math.max(alternativeMaxWidth,
weightedMaxWidth);
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// We have no limit, so make all weighted views as tall as the largest child.</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Children will have already been measured once.</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (useLargestChild && heightMode != MeasureSpec.EXACTLY) {
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">for</span> (<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> i = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>; i < count; i++) {
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> View child = getVirtualChildAt(i);
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (child == <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">null</span> || child.getVisibility() == View.GONE) {
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">continue</span>;
}
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> LinearLayout.LayoutParams lp =
(LinearLayout.LayoutParams) child.getLayoutParams();
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">float</span> childExtra = lp.weight;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (childExtra > <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>) {
child.measure(
MeasureSpec.makeMeasureSpec(child.getMeasuredWidth(),
MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(largestChildHeight,
MeasureSpec.EXACTLY));
}
}
}
}
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (!allFillParent && widthMode != MeasureSpec.EXACTLY) {
maxWidth = alternativeMaxWidth;
}
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 调整 width 大小</span>
maxWidth += mPaddingLeft + mPaddingRight;
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Check against our minimum width</span>
maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 调用 setMeasuredDimension() 设置 LinearLayout 的大小</span>
setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
heightSizeAndState);
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//最后,设置LinearLayout的size大小和状态,如果LinearLayout有设置width为match_parent的话,将会调用forceUniformWidth再测量一次所有的subchild,这里主要是测量subchild的width大小</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (matchWidth) {
forceUniformWidth(count, heightMeasureSpec);
}
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">假如一共有3个subchild且都有设置weight ,分别为3、2、1,我们假设剩余的space为120,则第一个view的大小为120 * 3/(3+2+1)=60,第二个view的大小为(120-60)*2/(2+1)=40,第3个view的大小为(60-40)*1/1 = 20</p>
<h6 style="line-height: 160%; box-sizing: content-box; font-size: 13px; color: #333;">resolveSizeAndState</h6>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">public</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">static</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">resolveSizeAndState</span><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> size, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> measureSpec, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> childMeasuredState)</span> </span>{
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> specMode = MeasureSpec.getMode(measureSpec);
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> specSize = MeasureSpec.getSize(measureSpec);
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">final</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> result;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">switch</span> (specMode) {
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">case</span> MeasureSpec.AT_MOST:
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (specSize < size) {
result = specSize | MEASURED_STATE_TOO_SMALL;
} <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> {
result = size;
}
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">break</span>;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">case</span> MeasureSpec.EXACTLY:
result = specSize;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">break</span>;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">case</span> MeasureSpec.UNSPECIFIED:
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">default</span>:
result = size;
}
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> result | (childMeasuredState & MEASURED_STATE_MASK);
}
</code></pre>
<h6 style="line-height: 160%; box-sizing: content-box; font-size: 13px; color: #333;">总结</h6>
<ol style="line-height: 160%; box-sizing: content-box; display: block; padding-left: 30px; margin: 6px 0 10px; color: #333; list-style-type: decimal;">
<li style="line-height: 160%; box-sizing: content-box;">LinearLayout针对设置weight与不设置weight的情况分别处理</li>
<li style="line-height: 160%; box-sizing: content-box;">在 LinearLayout 中总共有 3 个 for 循环,分别处理不同的流程
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333; margin-top: 0; margin-bottom: 0;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">第一个 for 循环,只会在不使用 weight 属性时进入,并有可能会测量每个 childView 的大小</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">第二个 for 循环,在使用 android:measureWithLargestChild 时才会进入,并且即使进入也不会调用 childView 的测量方法,只会更新 mTotalLength 变量</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">第三个 for 循环,只会在使用 weight 属性时进入,并测量每个 childView 的大小</li>
</ul>
</li>
</ol>
<h3 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 27px; color: #333;">自定义View总结</h3>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">自定义UI基础</h4>
<ol style="line-height: 160%; box-sizing: content-box; display: block; padding-left: 30px; margin: 6px 0 10px; color: #333; list-style-type: decimal;">
<li style="line-height: 160%; box-sizing: content-box;">Android的坐标系</li>
</ol>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><img src="UI总结_files/Image.png" type="image/png" data-filename="Image.png"/><br/>
<img src="UI总结_files/Image [1].png" type="image/png" data-filename="Image.png"/><br/>
<img src="UI总结_files/Image [2].png" type="image/png" data-filename="Image.png"/></p>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">View的静态坐标方法</li>
</ul>
<table style="margin: 2px 0 14px; color: #333; width: auto; border-collapse: collapse; box-sizing: border-box;"><thead style="line-height: 160%; box-sizing: content-box;"><tr style="line-height: 160%; box-sizing: content-box;"><th style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #72777b; border-top: 0; background-color: #7b8184; font-weight: 300; color: #fff; padding-top: 6px;">View的静态坐标方法</th><th style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #72777b; border-top: 0; background-color: #7b8184; font-weight: 300; color: #fff; padding-top: 6px; text-align: left;">解释</th></tr></thead><tbody style="line-height: 160%; box-sizing: content-box;"><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">getLeft()</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: left;">返回View自身左边到父布局左边的距离</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">getTop()</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: left;">返回View自身顶边到父布局顶边的距离</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">getRight()</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: left;">返回View自身右边到父布局左边的距离</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">getBottom()</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: left;">返回View自身底边到父布局顶边的距离</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">getX()</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: left;">返回值为getLeft()+getTranslationX(),当setTranslationX()时getLeft()不变,getX()变。</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">getY()</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: left;">返回值为getTop()+getTranslationY(),当setTranslationY()时getTop()不变,getY()变。</td></tr></tbody></table>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">手指触摸屏幕时MotionEvent</li>
</ul>
<table style="margin: 2px 0 14px; color: #333; width: auto; border-collapse: collapse; box-sizing: border-box;"><thead style="line-height: 160%; box-sizing: content-box;"><tr style="line-height: 160%; box-sizing: content-box;"><th style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #72777b; border-top: 0; background-color: #7b8184; font-weight: 300; color: #fff; padding-top: 6px;">MotionEvent坐标方法</th><th style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #72777b; border-top: 0; background-color: #7b8184; font-weight: 300; color: #fff; padding-top: 6px;">解释</th></tr></thead><tbody style="line-height: 160%; box-sizing: content-box;"><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">getX()</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">当前触摸事件距离当前View左边的距离</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">getY()</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">当前触摸事件距离当前View顶边的距离</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">getRawX()</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">当前触摸事件距离整个屏幕左边的距离</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">getRawY()</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">当前触摸事件距离整个屏幕顶边的距离</td></tr></tbody></table>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">获取宽高</li>
</ul>
<table style="margin: 2px 0 14px; color: #333; width: auto; border-collapse: collapse; box-sizing: border-box;"><thead style="line-height: 160%; box-sizing: content-box;"><tr style="line-height: 160%; box-sizing: content-box;"><th style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #72777b; border-top: 0; background-color: #7b8184; font-weight: 300; color: #fff; padding-top: 6px;">View宽高方法</th><th style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #72777b; border-top: 0; background-color: #7b8184; font-weight: 300; color: #fff; padding-top: 6px;">解释</th></tr></thead><tbody style="line-height: 160%; box-sizing: content-box;"><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">getWidth()</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">layout后有效,返回值是mRight-mLeft,一般会参考measure的宽度(measure可能没用),但不是必须的。</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">getHeight()</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">layout后有效,返回值是mBottom-mTop,一般会参考measure的高度(measure可能没用),但不是必须的。</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">getMeasuredWidth()</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">返回measure过程得到的mMeasuredWidth值,供layout参考,或许没用。</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">getMeasuredHeight()</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">返回measure过程得到的mMeasuredHeight值,供layout参考,或许没用。</td></tr></tbody></table>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">获取view位置</li>
</ul>
<table style="margin: 2px 0 14px; color: #333; width: auto; border-collapse: collapse; box-sizing: border-box;"><thead style="line-height: 160%; box-sizing: content-box;"><tr style="line-height: 160%; box-sizing: content-box;"><th style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #72777b; border-top: 0; background-color: #7b8184; font-weight: 300; color: #fff; padding-top: 6px;">View的方法</th><th style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #72777b; border-top: 0; background-color: #7b8184; font-weight: 300; color: #fff; padding-top: 6px;">结论描述</th></tr></thead><tbody style="line-height: 160%; box-sizing: content-box;"><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">getLocalVisibleRect()</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">获取View自身可见的坐标区域,坐标以自己的左上角为原点(0,0),另一点为可见区域右下角相对自己(0,0)点的坐标,其实View2当前height为550,可见height为470。</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">getGlobalVisibleRect()</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">获取View在屏幕绝对坐标系中的可视区域,坐标以屏幕左上角为原点(0,0),另一个点为可见区域右下角相对屏幕原点(0,0)点的坐标。</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">getLocationOnScreen()</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">坐标是相对整个屏幕而言,Y坐标为View左上角到屏幕顶部的距离。</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">getLocationInWindow()</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">如果为普通Activity则Y坐标为View左上角到屏幕顶部(此时Window与屏幕一样大);如果为对话框式的Activity则Y坐标为当前Dialog模式Activity的标题栏顶部到View左上角的距离。</td></tr></tbody></table>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">View滑动相关坐标系</li>
</ul>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">View的scrollTo()和scrollBy()是用于滑动View中的内容,而不是改变View的位置;改变View在屏幕中的位置可以使用offsetLeftAndRight()和offsetTopAndBottom()方法,他会导致getLeft()等值改变</p>
<table style="margin: 2px 0 14px; color: #333; width: auto; border-collapse: collapse; box-sizing: border-box;"><thead style="line-height: 160%; box-sizing: content-box;"><tr style="line-height: 160%; box-sizing: content-box;"><th style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #72777b; border-top: 0; background-color: #7b8184; font-weight: 300; color: #fff; padding-top: 6px;">View的滑动方法</th><th style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #72777b; border-top: 0; background-color: #7b8184; font-weight: 300; color: #fff; padding-top: 6px;">效果及描述</th></tr></thead><tbody style="line-height: 160%; box-sizing: content-box;"><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">offsetLeftAndRight(int offset)</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">水平方向挪动View,offset为正则x轴正向移动,移动的是整个View,getLeft()会变的,<strong style="line-height: 160%; box-sizing: content-box; font-weight: 700;">自定义View很有用</strong>。</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">offsetTopAndBottom(int offset)</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">垂直方向挪动View,offset为正则y轴正向移动,移动的是整个View,getTop()会变的,<strong style="line-height: 160%; box-sizing: content-box; font-weight: 700;">自定义View很有用</strong>。</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">scrollTo(int x, int y)</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">将**View中内容(不是整个View)**滑动到相应的位置,参考坐标原点为ParentView左上角,x,y为正则向xy轴反方向移动,反之同理。</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">scrollBy(int x, int y)</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">在scrollTo()的基础上继续滑动xy。</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">setScrollX(int value)</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">实质为scrollTo(),只是只改变Y轴滑动。</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">setScrollY(int value)</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">实质为scrollTo(),只是只改变X轴滑动。</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">getScrollX()/getScrollY()</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">获取当前滑动位置偏移量。</td></tr></tbody></table>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><img src="UI总结_files/Image [3].png" type="image/png" data-filename="Image.png"/></p>
<ol start="2" style="line-height: 160%; box-sizing: content-box; display: block; padding-left: 30px; margin: 6px 0 10px; color: #333; list-style-type: decimal;">
<li style="line-height: 160%; box-sizing: content-box;">自定义view分类</li>
</ol>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">
<p style="line-height: 160%; box-sizing: content-box; color: #333; margin: 0;">自定义View的基本方法<br/>
自定义View的最基本的三个方法分别是: onMeasure()、onLayout()、onDraw();<br/>
View在Activity中显示出来,要经历测量、布局和绘制三个步骤,分别对应三个动作:measure、layout和draw。</p>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333; margin-top: 0; margin-bottom: 0;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">测量:onMeasure()决定View的大小;</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">布局:onLayout()决定View在ViewGroup中的位置;</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">绘制:onDraw()决定绘制这个View。</li>
</ul>
</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">
<p style="line-height: 160%; box-sizing: content-box; color: #333; margin: 0;">自定义控件分类</p>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333; margin-top: 0; margin-bottom: 0;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">自定义View: 只需要重写onMeasure()和onDraw()</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">自定义ViewGroup: 则只需要重写onMeasure()和onLayout()</li>
</ul>
</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">
<p style="line-height: 160%; box-sizing: content-box; color: #333; margin: 0;">视图View主要分为两类</p>
</li>
</ul>
<table style="margin: 2px 0 14px; color: #333; width: auto; border-collapse: collapse; box-sizing: border-box;"><thead style="line-height: 160%; box-sizing: content-box;"><tr style="line-height: 160%; box-sizing: content-box;"><th style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #72777b; border-top: 0; background-color: #7b8184; font-weight: 300; color: #fff; padding-top: 6px;">类别</th><th style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #72777b; border-top: 0; background-color: #7b8184; font-weight: 300; color: #fff; padding-top: 6px;">解释</th><th style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #72777b; border-top: 0; background-color: #7b8184; font-weight: 300; color: #fff; padding-top: 6px;">特点</th></tr></thead><tbody style="line-height: 160%; box-sizing: content-box;"><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">单一视图</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">即一个View,如TextView</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">不包含子View</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">视图组</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">即多个View组成的ViewGroup,如LinearLayout</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea;">包含子View</td></tr></tbody></table>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">
<p style="line-height: 160%; box-sizing: content-box; color: #333; margin: 0;">View类简介</p>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333; margin-top: 0; margin-bottom: 0;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">View类是Android中各种组件的基类,如View是ViewGroup基类</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">View表现为显示在屏幕上的各种视图</li>
</ul>
<blockquote style="line-height: 160%; box-sizing: content-box; margin: 15px 0; border-left: 4px solid #ddd; padding: 0 15px; color: #777;">
<p style="line-height: 160%; box-sizing: content-box; color: #333; margin-top: 0; margin-bottom: 0; margin: 0;">Android中的UI组件都由View、ViewGroup组成。</p>
</blockquote>
</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">
<p style="line-height: 160%; box-sizing: content-box; color: #333; margin: 0;">View的构造函数:共有4个</p>
</li>
</ul>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 如果View是在Java代码里面new的,则调用第一个构造函数</span>
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">public</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">CustomView</span><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(Context context)</span> </span>{
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">super</span>(context);
}
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 如果View是在.xml里声明的,则调用第二个构造函数</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 自定义属性是从AttributeSet参数传进来的</span>
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">public</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">CustomView</span><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(Context context, AttributeSet attrs)</span> </span>{
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">super</span>(context, attrs);
}
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 不会自动调用</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 一般是在第二个构造函数里主动调用</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 如View有style属性时</span>
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">public</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">CustomView</span><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(Context context, AttributeSet attrs, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> defStyleAttr)</span> </span>{
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">super</span>(context, attrs, defStyleAttr);
}
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//API21之后才使用</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 不会自动调用</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 一般是在第二个构造函数里主动调用</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 如View有style属性时</span>
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">public</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">CustomView</span><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(Context context, AttributeSet attrs, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> defStyleAttr, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> defStyleRes)</span> </span>{
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">super</span>(context, attrs, defStyleAttr, defStyleRes);
}
</code></pre>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">
<p style="line-height: 160%; box-sizing: content-box; color: #333; margin: 0;">AttributeSet与自定义属性<br/>
系统自带的View可以在xml中配置属性,对于写的好的自定义View同样可以在xml中配置属性,为了使自定义的View的属性可以在xml中配置,需要以下4个步骤:</p>
<ol style="line-height: 160%; box-sizing: content-box; display: block; padding-left: 30px; margin: 6px 0 10px; color: #333; list-style-type: decimal; margin-top: 0; margin-bottom: 0;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">通过<code style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; color: #c1788b; padding: 4px 4px 2px 0; letter-spacing: -.3px;"><declare-styleable></code>为自定义View添加属性</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">在xml中为相应的属性声明属性值</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">在运行时(一般为构造函数)获取属性值</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">将获取到的属性值应用到View</li>
</ol>
</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">
<p style="line-height: 160%; box-sizing: content-box; color: #333; margin: 0;">View视图结构</p>
<ol style="line-height: 160%; box-sizing: content-box; display: block; padding-left: 30px; margin: 6px 0 10px; color: #333; list-style-type: decimal; margin-top: 0; margin-bottom: 0;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">PhoneWindow是Android系统中最基本的窗口系统,继承自Windows类,负责管理界面显示以及事件响应。它是Activity与View系统交互的接口</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">DecorView是PhoneWindow中的起始节点View,继承于View类,作为整个视图容器来使用。用于设置窗口属性。它本质上是一个FrameLayout</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">ViewRoot在Activtiy启动时创建,负责管理、布局、渲染窗口UI等等</li>
</ol>
</li>
</ul>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><img src="UI总结_files/Image [4].png" type="image/png" data-filename="Image.png"/></p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">上图是 Activity 的结构。我们先进行大致的描述,然后在进入源码体会这一过程。</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">我们可以清晰的知道一个 Activity 会对应着有一个 Window,而 Window 的唯一实现类为 PhoneWindow,PhoneWindow 的初始化是在 Activity 的 attach 方法中,我们前面也有提到 attach 方法。</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">在往下一层是一个 DecorView,被 PhoneWindow 持有着,DecorView 的初始化在 setContentView 中,这个我们待会会进行详细分析。DecorView 是我们的顶级View,我们设置的布局只是其子View。</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">DecorView 是一个 FrameLayout。但在 setContentView 中,会给他加入一个线性的布局(LinearLayout)。该线性布局的子View 则一般由 TitleBar 和 ContentView 进行组成。TitleBar 我们可以通过 requestWindowFeature(Window.FEATURE_NO_TITLE); 进行去除,而 ContentView 则是来装载我们设置的布局文件的 ViewGroup 了</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">对于多View的视图,结构是树形结构:最顶层是ViewGroup,ViewGroup下可能有多个ViewGroup或View,如下图:</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><img src="UI总结_files/Image [5].png" type="image/png" data-filename="Image.png"/></p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">一定要记住:无论是measure过程、layout过程还是draw过程,永远都是从View树的根节点开始测量或计算(即从树的顶端开始),一层一层、一个分支一个分支地进行(即树形递归),最终计算整个View树中各个View,最终确定整个View树的相关属性</p>
<h6 style="line-height: 160%; box-sizing: content-box; font-size: 13px; color: #333;">view的生命周期</h6>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><img src="UI总结_files/Image [6].png" type="image/png" data-filename="Image.png"/></p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><img src="UI总结_files/Image [7].png" type="image/png" data-filename="Image.png"/></p>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">绘制流程从何而起</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">我们一说到绘制流程,就会想到或是听过onMeasure、onLayout、onDraw这三个方法,但是有没想过为什么我们开启一个App或是点开一个Activity,就会触发这一系列流程呢?想知道绘制流程从何而起,我们就有必要先解释 App启动流程 和 Activity的启动流程。我们都知道</p>
<blockquote style="line-height: 160%; box-sizing: content-box; margin: 15px 0; border-left: 4px solid #ddd; padding: 0 15px; color: #777;">
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333; margin-top: 0; margin-bottom: 0;">ActivityThread 的 main 是一个App的入口。我们来到 main 方法看看他做了什么启动操作。ActivityThread 的 main方法是由 ZygoteInit 类中最终通过 RuntimeInit类的invokeStaticMain 方法进行反射调用</p>
</blockquote>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><img src="UI总结_files/Image [8].png" type="image/png" data-filename="Image.png"/></p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><img src="UI总结_files/Image [9].png" type="image/png" data-filename="Image.png"/></p>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">measure流程</li>
</ul>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><img src="UI总结_files/Image [10].png" type="image/png" data-filename="Image.png"/></p>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">layout流程</li>
</ul>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><img src="UI总结_files/Image [11].png" type="image/png" data-filename="Image.png"/></p>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">draw流程</li>
</ul>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><img src="UI总结_files/Image [12].png" type="image/png" data-filename="Image.png"/></p>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">刷新</li>
</ul>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><img src="UI总结_files/Image [13].png" type="image/png" data-filename="Image.png"/></p>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">测量是如何进行的</h4>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">
<p style="line-height: 160%; box-sizing: content-box; color: #333; margin: 0;">测量遍历在 measure(int, int) 中实现,是 View 树的自上而下遍历。在递归过程中,每个 View 都会将维度规范下推到布局树。在测量遍历结束时,每个 View 均存储了其测量值。第二次遍历发生在 layout(int, int, int, int) 中,也是自上而下遍历。在此次遍历中,每个父级负责使用测量遍历中计算的尺寸来定位其所有的子级。当返回 View 对象的 measure() 方法时,必须设置其 getMeasuredWidth() 和 getMeasuredHeight() 值,以及该 View 对象的所有子级的值。View 对象的测量宽度值和测量高度值必须遵守 View 对象的父级所施加的限制。这就保证了在测量遍历结束时,所有父级都会接受其子级的所有测量值。父级 View 可以对其子级多次调用 measure()。例如,父级可以使用未指定的维度测量每个子级一次,以确定它们希望的大小;然后,如果所有子级不受限制的尺寸的总和过大或过小,则再次使用实际的数字对它们调用 measure()(即,如果子级未就各自获得多少空间达成一致,则父级将会介入并针对第二次遍历设置规则)。</p>
</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">
<p style="line-height: 160%; box-sizing: content-box; color: #333; margin: 0;">测量遍历使用两个类来传达维度。View 对象使用 ViewGroup.LayoutParams 类来告知父级它们想要如何测量和定位。基本的 ViewGroup.LayoutParams 类仅描述了 View 希望的宽度和高度。针对每个维度,它可以指定以下某一项:</p>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333; margin-top: 0; margin-bottom: 0;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">一个确切的数字</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">MATCH_PARENT,该参数意味着 View 想要和它的父级一样大(负填充)</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">WRAP_CONTENT,该参数意味着 View 想要足够大,以包含其内容(正填充)。</li>
</ul>
</li>
</ul>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">有适用于 ViewGroup 的不同子类的 ViewGroup.LayoutParams 子类。例如,RelativeLayout 有自己的 ViewGroup.LayoutParams 子类,其中包括使子级 View 对象水平和垂直居中的功能。</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">MeasureSpec 对象用于在树中将要求从父级下推到子级。MeasureSpec 可以为以下三种模式之一:</p>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">UNSPECIFIED:父级使用该模式来确定子级 View 所需的维度。例如,LinearLayout 可能会对其高度设置为 UNSPECIFIED 和宽度设置为 EXACTLY 240 的子级调用 measure(),从而确定宽度为 240 像素的子级 View 所需的高度。</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">EXACTLY:父级使用该模式来强制子级使用某个确切尺寸。子级必须使用该尺寸,并保证其所有的子项都能放入该尺寸。</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">AT MOST:父级使用该模式来强制规定子级的最大尺寸。子级必须保证它及其所有的子项都能放入该尺寸</li>
</ul>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><img src="UI总结_files/Image [14].png" type="image/png" data-filename="Image.png"/></p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ViewGroup 类</span>
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">public</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">static</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">getChildMeasureSpec</span><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> spec, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> padding, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> childDimension)</span> </span>{
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> specMode = MeasureSpec.getMode(spec);
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> specSize = MeasureSpec.getSize(spec);
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> size = Math.max(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>, specSize - padding);
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> resultSize = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">int</span> resultMode = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">switch</span> (specMode) {
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 父视图为确定的大小的模式</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">case</span> MeasureSpec.EXACTLY:
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">/**
* 根据子视图的大小,进行不同模式的组合:
* 1、childDimension 大于 0,说明子视图设置了具体的大小
* 2、childDimension 为 {<span style="color: #608b4e; line-height: 160%; box-sizing: content-box;">@link</span> LayoutParams.MATCH_PARENT},说明大小和其父视图一样大
* 3、childDimension 为 {<span style="color: #608b4e; line-height: 160%; box-sizing: content-box;">@link</span> LayoutParams.WRAP_CONTENT},说明子视图想为其自己的大小,但
* 不能超过其父视图的大小。
*/</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (childDimension >= <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>) {
resultSize = childDimension;
resultMode = MeasureSpec.EXACTLY;
} <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (childDimension == LayoutParams.MATCH_PARENT) {
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Child wants to be our size. So be it.</span>
resultSize = size;
resultMode = MeasureSpec.EXACTLY;
} <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (childDimension == LayoutParams.WRAP_CONTENT) {
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Child wants to determine its own size. It can't be</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// bigger than us.</span>
resultSize = size;
resultMode = MeasureSpec.AT_MOST;
}
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">break</span>;
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 父视图已经有一个最大尺寸限制</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">case</span> MeasureSpec.AT_MOST:
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">/**
* 根据子视图的大小,进行不同模式的组合:
* 1、childDimension 大于 0,说明子视图设置了具体的大小
* 2、childDimension 为 {<span style="color: #608b4e; line-height: 160%; box-sizing: content-box;">@link</span> LayoutParams.MATCH_PARENT},
* -----说明大小和其父视图一样大,但是此时的父视图还不能确定其大小,所以只能让子视图不超过自己
* 3、childDimension 为 {<span style="color: #608b4e; line-height: 160%; box-sizing: content-box;">@link</span> LayoutParams.WRAP_CONTENT},
* -----说明子视图想为其自己的大小,但不能超过其父视图的大小。
*/</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (childDimension >= <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>) {
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Child wants a specific size... so be it</span>
resultSize = childDimension;
resultMode = MeasureSpec.EXACTLY;
} <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (childDimension == LayoutParams.MATCH_PARENT) {
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Child wants to be our size, but our size is not fixed.</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Constrain child to not be bigger than us.</span>
resultSize = size;
resultMode = MeasureSpec.AT_MOST;
} <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (childDimension == LayoutParams.WRAP_CONTENT) {
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Child wants to determine its own size. It can't be</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// bigger than us.</span>
resultSize = size;
resultMode = MeasureSpec.AT_MOST;
}
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">break</span>;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">case</span> MeasureSpec.UNSPECIFIED:
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (childDimension >= <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>) {
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Child wants a specific size... let him have it</span>
resultSize = childDimension;
resultMode = MeasureSpec.EXACTLY;
} <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (childDimension == LayoutParams.MATCH_PARENT) {
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Child wants to be our size... find out how big it should</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// be</span>
resultSize = View.sUseZeroUnspecifiedMeasureSpec ? <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span> : size;
resultMode = MeasureSpec.UNSPECIFIED;
} <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (childDimension == LayoutParams.WRAP_CONTENT) {
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Child wants to determine its own size.... find out how</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// big it should be</span>
resultSize = View.sUseZeroUnspecifiedMeasureSpec ? <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span> : size;
resultMode = MeasureSpec.UNSPECIFIED;
}
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">break</span>;
}
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> MeasureSpec.makeMeasureSpec(resultSize, resultMode);}
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><img src="UI总结_files/Image [15].png" type="image/png" data-filename="Image.png"/></p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">针对上表,这里再做一下具体的说明</p>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">对于应用层 View ,其 MeasureSpec 由父容器的 MeasureSpec 和自身的 LayoutParams 来共同决定</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">对于不同的父容器和view本身不同的LayoutParams,view就可以有多种MeasureSpec。<br/>
1. 当view采用固定宽高的时候,不管父容器的MeasureSpec是什么,view的MeasureSpec都是精确模式并且其大小遵循Layoutparams中的大小;<br/>
2. 当view的宽高是match_parent时,这个时候如果父容器的模式是精准模式,那么view也是精准模式并且其大小是父容器的剩余空间,如果父容器是最大模式,那么view也是最大模式并且其大小不会超过父容器的剩余空间;<br/>
3. 当view的宽高是wrap_content时,不管父容器的模式是精准还是最大化,view的模式总是最大化并且大小不能超过父容器的剩余空间。<br/>
4. Unspecified模式,这个模式主要用于系统内部多次measure的情况下,一般来说,我们不需要关注此模式(这里注意自定义View放到ScrollView的情况 需要处理)。</li>
</ul>
<h6 style="line-height: 160%; box-sizing: content-box; font-size: 13px; color: #333;">onMeasure()方法中常用的方法</h6>
<ol style="line-height: 160%; box-sizing: content-box; display: block; padding-left: 30px; margin: 6px 0 10px; color: #333; list-style-type: decimal;">
<li style="line-height: 160%; box-sizing: content-box;">getChildCount():获取子View的数量;</li>
<li style="line-height: 160%; box-sizing: content-box;">getChildAt(i):获取第i个子控件;</li>
<li style="line-height: 160%; box-sizing: content-box;">subView.getLayoutParams().width/height:设置或获取子控件的宽或高;</li>
<li style="line-height: 160%; box-sizing: content-box;">measureChild(child, widthMeasureSpec, heightMeasureSpec):测量子View的宽高;</li>
<li style="line-height: 160%; box-sizing: content-box;">child.getMeasuredHeight/width():执行完measureChild()方法后就可以通过这种方式获取子View的宽高值;</li>
<li style="line-height: 160%; box-sizing: content-box;">getPaddingLeft/Right/Top/Bottom():获取控件的四周内边距;</li>
<li style="line-height: 160%; box-sizing: content-box;">setMeasuredDimension(width, height):重新设置控件的宽高</li>
</ol>
<h6 style="line-height: 160%; box-sizing: content-box; font-size: 13px; color: #333;">自定义View需要注意的地方</h6>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">让View支持wrap_conent</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">让View支持padding</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">尽量避免使用Handler,一般都可以用View自带的post方法代替</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">在onDeatchFromWindow时,停止View的动画或线程(如果有的话)</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">如果存在嵌套滑动,处理好滑动冲突</li>
</ul>
<h6 style="line-height: 160%; box-sizing: content-box; font-size: 13px; color: #333;">自定义View如何测量</h6>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><img src="UI总结_files/Image [16].png" type="image/png" data-filename="Image.png"/></p>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">自定义绘制</h4>
<ol style="line-height: 160%; box-sizing: content-box; display: block; padding-left: 30px; margin: 6px 0 10px; color: #333; list-style-type: decimal;">
<li style="line-height: 160%; box-sizing: content-box;">
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">Canvas常用方法</p>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333; margin-top: 0; margin-bottom: 0;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">绘制图形(点、线、矩形、椭圆、圆等)</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">绘制文本(文本的居中问题,需要Paint知识)</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">画布的基本变化(平移、缩放、旋转、倾斜)</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">画布的裁剪</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">画布的保存<br/>
<img src="UI总结_files/Image [17].png" type="image/png" data-filename="Image.png"/></li>
</ul>
</li>
<li style="line-height: 160%; box-sizing: content-box;">
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">Paint类主要用于设置绘制风格:包括画笔的颜色画笔触笔粗细、填充风格及文字的特征</p>
</li>
</ol>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">Paint常用方法
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333; margin-top: 0; margin-bottom: 0;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">颜色</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">类型(填充、描边)</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">字体大小</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">宽度</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">对齐方式</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">文字位置属性测量</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">文字宽度测量<br/>
<img src="UI总结_files/Image [18].png" type="image/png" data-filename="Image.png"/><br/>
<img src="UI总结_files/Image [19].png" type="image/png" data-filename="Image.png"/></li>
</ul>
</li>
</ul>
<ol start="3" style="line-height: 160%; box-sizing: content-box; display: block; padding-left: 30px; margin: 6px 0 10px; color: #333; list-style-type: decimal;">
<li style="line-height: 160%; box-sizing: content-box;">Path常用方法
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333; margin-top: 0; margin-bottom: 0;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">添加路径</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">移动起点</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">贝塞尔(二阶、三阶)</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">逻辑运算</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">重置路径</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">PathEffect</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">Matrix</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">PathMeasure</li>
</ul>
</li>
</ol>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">
<p style="line-height: 160%; box-sizing: content-box; color: #333; margin: 0;">PorterDuffXfermode<br/>
<img src="UI总结_files/Image [20].png" type="image/png" data-filename="Image.png"/></p>
</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">
<p style="line-height: 160%; box-sizing: content-box; color: #333; margin: 0;">Matrix<br/>
<img src="UI总结_files/Image [21].png" type="image/png" data-filename="Image.png"/></p>
</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">
<p style="line-height: 160%; box-sizing: content-box; color: #333; margin: 0;">平移矩阵<br/>
<img src="UI总结_files/Image [22].png" type="image/png" data-filename="Image.png"/></p>
</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">
<p style="line-height: 160%; box-sizing: content-box; color: #333; margin: 0;">缩放矩阵<br/>
<img src="UI总结_files/Image [23].png" type="image/png" data-filename="Image.png"/></p>
</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">
<p style="line-height: 160%; box-sizing: content-box; color: #333; margin: 0;">旋转矩阵<br/>
<img src="UI总结_files/Image [24].png" type="image/png" data-filename="Image.png"/></p>
</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">
<p style="line-height: 160%; box-sizing: content-box; color: #333; margin: 0;">ColorMatrix</p>
</li>
</ul>
<table style="margin: 2px 0 14px; color: #333; width: auto; border-collapse: collapse; box-sizing: border-box;"><thead style="line-height: 160%; box-sizing: content-box;"><tr style="line-height: 160%; box-sizing: content-box;"><th style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #72777b; border-top: 0; background-color: #7b8184; font-weight: 300; color: #fff; padding-top: 6px; text-align: left;">类别</th><th style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #72777b; border-top: 0; background-color: #7b8184; font-weight: 300; color: #fff; padding-top: 6px; text-align: center;">API</th><th style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #72777b; border-top: 0; background-color: #7b8184; font-weight: 300; color: #fff; padding-top: 6px; text-align: left;">描述</th></tr></thead><tbody style="line-height: 160%; box-sizing: content-box;"><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: left;">旋转</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: center;">setRotate</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: left;">设置(非输入轴颜色的)色调</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: left;">饱和度</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: center;">setSaturation</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: left;">设置饱和度</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: left;">缩放</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: center;">setScale</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: left;">三原色的取值的比例</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: left;">设置</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: center;">set、setConcat</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: left;">设置颜色矩阵、两个颜色矩阵的乘积</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: left;">重置</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: center;">reset</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: left;">重置颜色矩阵为初始状态</td></tr><tr style="line-height: 160%; box-sizing: content-box;"><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: left;">矩阵运算</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: center;">preConcat、postConcat</td><td style="line-height: 160%; box-sizing: content-box; padding: 5px 14px 5px 12px; border: 1px solid #eaeaea; text-align: left;">颜色矩阵的前乘、后乘</td></tr></tbody></table>
<ol start="4" style="line-height: 160%; box-sizing: content-box; display: block; padding-left: 30px; margin: 6px 0 10px; color: #333; list-style-type: decimal;">
<li style="line-height: 160%; box-sizing: content-box;">动画
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333; margin-top: 0; margin-bottom: 0;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">ObjectAnimator</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">ValueAnimator</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">AnimatorSet</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">差值器</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">估值器</li>
</ul>
</li>
</ol>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">事件分发</h4>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">事件序列 DOWN -> ... MOVE .... -> UP/CANCEL</li>
</ul>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><img src="UI总结_files/Image [25].png" type="image/png" data-filename="Image.png"/></p>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">父容器调用哪个方法可以拦截子View的事件?为什么?
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333; margin-top: 0; margin-bottom: 0;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">调用onInterceptTouchEvent()并返回true。因为该方法返回true后,会导致变量 intercepted = true,从而导致不会走后面分发事件的代码。</li>
</ul>
</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">子View调用哪个方法可以请求父容器不拦截自己?为什么?
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333; margin-top: 0; margin-bottom: 0;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">requestDisallowInterceptTouchEvent(true)。因为 onInterceptTouchEvent() 方法的执行条件是disallowIntercept = false,而子View调用requestDisallowInterceptTouchEvent(true)方法可以导致disallowIntercept = true,从而onInterceptTouchEvent方法不会执行,父容器就不能拦截自己了。</li>
</ul>
</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">父容器一旦在down事件拦截子View,就算子View调用了requestDisallowInterceptTouchEvent方法还是拿不到事件,为什么?
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333; margin-top: 0; margin-bottom: 0;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">因为down事件时,父容器会调用resetTouchState,导致disallowIntercept始终为false,即onInterceptTouchEvent方法始终会执行。</li>
</ul>
</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">按钮的onClick方法是在哪个事件响应的?
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333; margin-top: 0; margin-bottom: 0;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">A.MotionEvent.ACTION_UP</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">B.MotionEvent.ACTION_DOWN</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">C.MotionEvent.ACTION_MOVE</li>
</ul>
</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">解决事件冲突的主要方法有哪些?
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333; margin-top: 0; margin-bottom: 0;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">内部拦截法、外部拦截法</li>
</ul>
</li>
</ul>
</div><center style="display:none !important;visibility:collapse !important;height:0 !important;white-space:nowrap;width:100%;overflow:hidden">%23%20%E9%AB%98%E7%BA%A7UI%0A%0A%23%23%23%20%E7%B3%BB%E7%BB%9FViewGroup%E5%8E%9F%E7%90%86%E8%A7%A3%E6%9E%90%0A%E5%B8%B8%E8%A7%81%E7%9A%84%E5%B8%83%E5%B1%80%E5%AE%B9%E5%99%A8%3A%20FrameLayout%2C%20LinearLayout%2CRelativeLayoout%2CGridLayout%0A%E5%90%8E%E8%B5%B7%E4%B9%8B%E7%A7%80%EF%BC%9AConstraintLayout%2CCoordinateLayout%0A%23%23%23%23%20Linearlayout%0A%0A%60%60%60java%0A%40Override%0A%20%20%20%20protected%20void%20onMeasure(int%20widthMeasureSpec%2C%20int%20heightMeasureSpec)%20%7B%0A%20%20%20%20%20%20%20%20if%20(mOrientation%20%3D%3D%20VERTICAL)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20measureVertical(widthMeasureSpec%2C%20heightMeasureSpec)%3B%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20measureHorizontal(widthMeasureSpec%2C%20heightMeasureSpec)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%60%60%60%0A%0AonMeasure(int%20widthMeasureSpec%2C%20int%20heightMeasureSpec)%20%E6%BA%90%E7%A0%81%E5%A6%82%E4%B8%8A%E6%89%80%E7%A4%BA%EF%BC%8C%E9%80%9A%E8%BF%87%20mOrientation%20%E5%88%86%E5%88%AB%E5%A4%84%E7%90%86%E5%9E%82%E7%9B%B4%E5%92%8C%E6%B0%B4%E5%B9%B3%E4%B8%A4%E4%B8%AA%E6%96%B9%E5%90%91%E7%9A%84%E6%B5%8B%E9%87%8F%EF%BC%8C%E5%85%B6%E4%B8%AD%E7%9A%84%20mOrientation%20%E5%8F%98%E9%87%8F%E5%88%99%E6%98%AF%E6%88%91%E4%BB%AC%E5%9C%A8%20xml%20%E5%B8%83%E5%B1%80%E6%96%87%E4%BB%B6%E4%B8%AD%E9%80%9A%E8%BF%87%20android%3Aorientation%3D%22vertical%22%20%E6%88%96%E8%80%85%E7%9B%B4%E6%8E%A5%E9%80%9A%E8%BF%87%20setOrientation(%40OrientationMode%20int%20orientation)%20%E6%96%B9%E6%B3%95%E8%AE%BE%E7%BD%AE%E7%9A%84%20LinearLayout%20%E6%96%87%E4%BB%B6%E6%96%B9%E5%90%91%E5%8F%98%E9%87%8F%0A%0A%E6%88%91%E4%BB%AC%E4%BB%85%E5%88%86%E6%9E%90%E5%9E%82%E7%9B%B4%E6%96%B9%E5%90%91%E7%9A%84%E6%B5%8B%E9%87%8F%E6%96%B9%E6%B3%95%EF%BC%8C%E4%B9%9F%E5%B0%B1%E6%98%AF%20measureVertical(int%20widthMeasureSpec%2C%20int%20heightMeasureSpec)%EF%BC%88%E6%B0%B4%E5%B9%B3%E6%96%B9%E5%90%91%E7%9A%84%E6%B5%8B%E9%87%8F%E6%96%B9%E6%B3%95%20measureHorizontal(int%20widthMeasureSpec%2C%20int%20heightMeasureSpec)%20%E6%98%AF%E7%B1%BB%E4%BC%BC%E7%9A%84%E5%8E%9F%E7%90%86%EF%BC%8C%E6%9C%89%E5%85%B4%E8%B6%A3%E7%9A%84%E6%9C%8B%E5%8F%8B%E5%8F%AF%E4%BB%A5%E8%87%AA%E5%B7%B1%E5%88%86%E6%9E%90%EF%BC%89%0A%0A%23%23%23%23%23%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E5%8F%98%E9%87%8F%0A%0A%E9%9C%80%E8%A6%81%E5%88%9D%E5%A7%8B%E5%8C%96%E4%B8%80%E4%BA%9B%E7%B1%BB%E5%8F%98%E9%87%8F%20%26%20%E5%A3%B0%E6%98%8E%E4%B8%80%E4%BA%9B%E9%87%8D%E8%A6%81%E7%9A%84%E5%B1%80%E9%83%A8%E5%8F%98%E9%87%8F%0A%0A%60%60%60java%0Avoid%20measureVertical(int%20widthMeasureSpec%2C%20int%20heightMeasureSpec)%20%7B%0A%2F%2F%E7%AC%AC%E4%B8%80%E9%98%B6%E6%AE%B5%EF%BC%8C%E4%B8%BB%E8%A6%81%E6%98%AF%E4%B8%80%E4%BA%9B%E5%8F%98%E9%87%8F%E7%9A%84%E5%88%9D%E5%A7%8B%E5%8C%96%0A%20%20%20%20%20%20%20%20mTotalLength%20%3D%200%3B%2F%2F%20%E6%89%80%E6%9C%89%20childView%20%E7%9A%84%E9%AB%98%E5%BA%A6%E5%92%8C%20%2B%20%E6%9C%AC%E8%BA%AB%E7%9A%84%20padding%EF%BC%8C%E6%B3%A8%E6%84%8F%EF%BC%9A%E5%AE%83%E5%92%8C%20LinearLayout%20%E6%9C%AC%E8%BA%AB%E7%9A%84%E9%AB%98%E5%BA%A6%E6%98%AF%E4%B8%8D%E5%90%8C%E7%9A%84%0A%20%20%20%20%20%20%20%20int%20maxWidth%20%3D%200%3B%2F%2F%20%E6%89%80%E6%9C%89%20childView%20%E4%B8%AD%E5%AE%BD%E5%BA%A6%E7%9A%84%E6%9C%80%E5%A4%A7%E5%80%BC%0A%20%20%20%20%20%20%20%20int%20childState%20%3D%200%3B%0A%20%20%20%20%20%20%20%20int%20alternativeMaxWidth%20%3D%200%3B%2F%2F%20%E6%89%80%E6%9C%89%20layout_weight%20%3C%3D%200%20%E7%9A%84%20childView%20%E4%B8%AD%E5%AE%BD%E5%BA%A6%E7%9A%84%E6%9C%80%E5%A4%A7%E5%80%BC%0A%20%20%20%20%20%20%20%20int%20weightedMaxWidth%20%3D%200%3B%2F%2F%20%E6%89%80%E6%9C%89%20layout_weight%20%3E0%20%E7%9A%84%20childView%20%E4%B8%AD%E5%AE%BD%E5%BA%A6%E7%9A%84%E6%9C%80%E5%A4%A7%E5%80%BC%0A%20%20%20%20%20%20%20%20boolean%20allFillParent%20%3D%20true%3B%0A%20%20%20%20%20%20%20%20float%20totalWeight%20%3D%200%3B%2F%2F%20%E6%89%80%E6%9C%89%20childView%20%E7%9A%84%20weight%20%E4%B9%8B%E5%92%8C%0A%0A%20%20%20%20%20%20%20%20final%20int%20count%20%3D%20getVirtualChildCount()%3B%0A%0A%20%20%20%20%20%20%20%20final%20int%20widthMode%20%3D%20MeasureSpec.getMode(widthMeasureSpec)%3B%0A%20%20%20%20%20%20%20%20final%20int%20heightMode%20%3D%20MeasureSpec.getMode(heightMeasureSpec)%3B%0A%0A%20%20%20%20%20%20%20%20boolean%20matchWidth%20%3D%20false%3B%0A%20%20%20%20%20%20%20%20boolean%20skippedMeasure%20%3D%20false%3B%0A%0A%20%20%20%20%20%20%20%20final%20int%20baselineChildIndex%20%3D%20mBaselineAlignedChildIndex%3B%0A%20%20%20%20%20%20%20%20final%20boolean%20useLargestChild%20%3D%20mUseLargestChild%3B%0A%0A%20%20%20%20%20%20%20%20int%20largestChildHeight%20%3D%20Integer.MIN_VALUE%3B%0A%20%20%20%20%20%20%20%20int%20consumedExcessSpace%20%3D%200%3B%0A%0A%20%20%20%20%20%20%20%20int%20nonSkippedChildCount%20%3D%200%3B%0A%20%20%20%20%20%20%20%20...%0A%EF%BD%9D%0A%60%60%60%0A%0A%23%23%23%23%23%23%20%E7%AC%AC%E4%B8%80%E6%AC%A1%E6%B5%8B%E9%87%8F%0A%0A%E5%9C%A8%E6%B5%8B%E9%87%8F%E7%AC%AC%E4%B8%80%E9%98%B6%E6%AE%B5%E4%BC%9A%E8%AE%A1%E7%AE%97%E9%82%A3%E4%BA%9B%E6%B2%A1%E6%9C%89%E8%AE%BE%E7%BD%AE%20weight%20%E7%9A%84%20childView%20%E7%9A%84%E9%AB%98%E5%BA%A6%E3%80%81%E8%AE%A1%E7%AE%97%C2%A0mTotleLength%EF%BC%8C%E5%B9%B6%E4%B8%94%E8%AE%A1%E7%AE%97%E4%B8%89%E4%B8%AA%E5%AE%BD%E5%BA%A6%E7%9B%B8%E5%85%B3%E7%9A%84%E5%8F%98%E9%87%8F%E7%9A%84%E5%80%BC%0A%0A%60%60%60java%0Avoid%20measureVertical(int%20widthMeasureSpec%2C%20int%20heightMeasureSpec)%20%7B%0A%2F%2F%E7%AC%AC%E4%BA%8C%E9%98%B6%E6%AE%B5%EF%BC%8C%E7%AC%AC%E4%B8%80%E6%AC%A1%E6%B5%8B%E9%87%8F%EF%BC%8C%E6%8E%A5%E4%B8%8A%E9%9D%A2%E4%BB%A3%E7%A0%81%0A%2F%2F%20See%20how%20tall%20everyone%20is.%20Also%20remember%20max%20width.%0A%2F%2F%E7%AC%AC%E4%B8%80%E9%81%8D%E5%BE%AA%E7%8E%AF%EF%BC%8C%E7%9C%8B%E7%9C%8B%E6%AF%8F%E4%B8%AAchildview%E7%9A%84%E9%AB%98%E5%BA%A6%EF%BC%8C%E5%B9%B6%E4%B8%94%E8%AE%B0%E5%BD%95%E6%9C%80%E5%A4%A7%E5%AE%BD%E5%BA%A6%0A%20%20%20%20%20%20%20%20for%20(int%20i%20%3D%200%3B%20i%20%3C%20count%3B%20%2B%2Bi)%20%7B%2F%2F%E4%B8%80%E5%B1%82for%E5%BE%AA%E7%8E%AF%0A%20%20%20%20%20%20%20%20%20%20%20%20final%20View%20child%20%3D%20getVirtualChildAt(i)%3B%2F%2F%E8%8E%B7%E5%8F%96%E5%88%B0%E6%AF%8F%E4%B8%80%E4%B8%AAchildview%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(child%20%3D%3D%20null)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mTotalLength%20%2B%3D%20measureNullChild(i)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(child.getVisibility()%20%3D%3D%20View.GONE)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20i%20%2B%3D%20getChildrenSkipCount(child%2C%20i)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20nonSkippedChildCount%2B%2B%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(hasDividerBeforeChildAt(i))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mTotalLength%20%2B%3D%20mDividerHeight%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20final%20LayoutParams%20lp%20%3D%20(LayoutParams)%20child.getLayoutParams()%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20totalWeight%20%2B%3D%20lp.weight%3B%2F%2F%E8%AE%A1%E7%AE%97%E6%80%BB%E6%9D%83%E9%87%8D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20final%20boolean%20useExcessSpace%20%3D%20lp.height%20%3D%3D%200%20%26%26%20lp.weight%20%3E%200%3B%2F%2F%E4%BD%BF%E7%94%A8%E4%BA%86%E6%9D%83%E9%87%8D%E6%89%8D%E4%BC%9A%E6%BB%A1%E8%B6%B3%0A%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E6%88%91%E4%BB%AC%E9%83%BD%E7%9F%A5%E9%81%93%EF%BC%8C%E6%B5%8B%E9%87%8F%E6%A8%A1%E5%BC%8F%E6%9C%89%E4%B8%89%E7%A7%8D%EF%BC%9A%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20*%20UNSPECIFIED%EF%BC%9A%E7%88%B6%E6%8E%A7%E4%BB%B6%E5%AF%B9%E5%AD%90%E6%8E%A7%E4%BB%B6%E6%97%A0%E7%BA%A6%E6%9D%9F%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20*%20Exactly%EF%BC%9A%E7%88%B6%E6%8E%A7%E4%BB%B6%E5%AF%B9%E5%AD%90%E6%8E%A7%E4%BB%B6%E5%BC%BA%E7%BA%A6%E6%9D%9F%EF%BC%8C%E5%AD%90%E6%8E%A7%E4%BB%B6%E6%B0%B8%E8%BF%9C%E5%9C%A8%E7%88%B6%E6%8E%A7%E4%BB%B6%E8%BE%B9%E7%95%8C%E5%86%85%EF%BC%8C%E8%B6%8A%E7%95%8C%E5%88%99%E8%A3%81%E5%89%AA%E3%80%82%E5%A6%82%E6%9E%9C%E8%A6%81%E8%AE%B0%E5%BF%86%E7%9A%84%E8%AF%9D%EF%BC%8C%E5%8F%AF%E4%BB%A5%E8%AE%B0%E5%BF%86%E4%B8%BA%E6%9C%89%E5%AF%B9%E5%BA%94%E7%9A%84%E5%85%B7%E4%BD%93%E6%95%B0%E5%80%BC%E6%88%96%E8%80%85%E6%98%AFMatch_parent%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20*%20AT_Most%EF%BC%9A%E5%AD%90%E6%8E%A7%E4%BB%B6%E4%B8%BAwrap_content%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E6%B5%8B%E9%87%8F%E5%80%BC%E4%B8%BAAT%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(heightMode%20%3D%3D%20MeasureSpec.EXACTLY%20%26%26%20useExcessSpace)%20%7B%2F%2F%E7%A1%AE%E5%88%87%E9%AB%98%E5%BA%A6%2C%E4%B8%94height%3D0%20%E6%9D%83%E9%87%8D%3E0%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Optimization%3A%20don't%20bother%20measuring%20children%20who%20are%20only%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20laid%20out%20using%20excess%20space.%20These%20views%20will%20get%20measured%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20later%20if%20we%20have%20space%20to%20distribute.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%E5%85%88%E8%B7%B3%E8%BF%87%E6%B5%8B%E9%87%8F%E6%A8%A1%E5%BC%8F%E4%B8%BAEXACTLY%E5%B9%B6%E4%B8%94%E9%9C%80%E8%A6%81%E6%9D%83%E9%87%8D%E8%AE%A1%E7%AE%97%E7%9A%84childview%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E5%9C%A8%E5%90%8E%E9%9D%A2%E7%AC%AC%E4%B8%89%E4%B8%AA%20for%20%E5%BE%AA%E7%8E%AF%E9%87%8D%E6%96%B0%E8%AE%A1%E7%AE%97%E6%AD%A4%20childView%20%E5%A4%A7%E5%B0%8F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20int%20totalLength%20%3D%20mTotalLength%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mTotalLength%20%3D%20Math.max(totalLength%2C%20totalLength%20%2B%20lp.topMargin%20%2B%20lp.bottomMargin)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20skippedMeasure%20%3D%20true%3B%2F%2F%E5%90%8E%E9%9D%A2%E8%B7%B3%E8%BF%87Measure%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%2F%2F%E9%AB%98%E5%BA%A6%E4%B8%8D%E6%98%AF%E7%A1%AE%E5%AE%9A%E5%8F%AF%E8%83%BD%E6%98%AFAT_MOST%2FUNSPECIFIED%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(useExcessSpace)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20The%20heightMode%20is%20either%20UNSPECIFIED%20or%20AT_MOST%2C%20and%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20this%20child%20is%20only%20laid%20out%20using%20excess%20space.%20Measure%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20using%20WRAP_CONTENT%20so%20that%20we%20can%20find%20out%20the%20view's%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20optimal%20height.%20We'll%20restore%20the%20original%20height%20of%200%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20after%20measurement.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%E6%8A%8A%E4%BD%BF%E7%94%A8%E6%9D%83%E9%87%8D%E7%9A%84childview%E7%9A%84%E9%AB%98%E5%BA%A6%E8%AE%BE%E7%BD%AE%E4%B8%BAwrap_content%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lp.height%20%3D%20LayoutParams.WRAP_CONTENT%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Determine%20how%20big%20this%20child%20would%20like%20to%20be.%20If%20this%20or%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20previous%20children%20have%20given%20a%20weight%2C%20then%20we%20allow%20it%20to%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20use%20all%20available%20space%20(and%20we%20will%20shrink%20things%20later%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20if%20needed).%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%E8%BF%99%E6%98%AF%E9%9D%9E%E5%B8%B8%E9%87%8D%E8%A6%81%E7%9A%84%E4%B8%80%E4%B8%AA%E6%96%B9%E6%B3%95%EF%BC%8C%E5%B0%86%E4%BC%9A%E5%86%B3%E5%AE%9A%E6%AF%8F%E4%B8%AA%20childView%20%E7%9A%84%E5%A4%A7%E5%B0%8F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%E5%A6%82%E6%9E%9C%E6%AD%A4%20childView%20%E5%8F%8A%E5%9C%A8%E6%AD%A4%20childView%20%E4%B9%8B%E5%89%8D%E7%9A%84%20childView%20%E4%B8%AD%E4%BD%BF%E7%94%A8%E4%BA%86%20weight%20%E5%B1%9E%E6%80%A7%EF%BC%8C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E6%88%91%E4%BB%AC%E5%85%81%E8%AE%B8%E6%AD%A4%20childView%20%E4%BD%BF%E7%94%A8%E6%89%80%E6%9C%89%E7%9A%84%E7%A9%BA%E9%97%B4%EF%BC%88%E5%90%8E%E7%BB%AD%E5%A6%82%E6%9E%9C%E9%9C%80%E8%A6%81%EF%BC%8C%E5%86%8D%E5%81%9A%E8%B0%83%E6%95%B4%EF%BC%89%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20int%20usedHeight%20%3D%20totalWeight%20%3D%3D%200%20%3F%20mTotalLength%20%3A%200%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%E8%B0%83%E7%94%A8viewgroup%E4%B8%AD%E6%96%B9%E6%B3%95%E6%B5%8B%E9%87%8F%E5%AD%90view%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20measureChildBeforeLayout(child%2C%20i%2C%20widthMeasureSpec%2C%200%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20heightMeasureSpec%2C%20usedHeight)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E5%BE%97%E5%88%B0%E6%B5%8B%E9%87%8F%E4%B9%8B%E5%90%8E%E7%9A%84%20childView%20%E7%9A%84%20childHeight%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20int%20childHeight%20%3D%20child.getMeasuredHeight()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(useExcessSpace)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Restore%20the%20original%20height%20and%20record%20how%20much%20space%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20we've%20allocated%20to%20excess-only%20children%20so%20that%20we%20can%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20match%20the%20behavior%20of%20EXACTLY%20measurement.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lp.height%20%3D%200%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20consumedExcessSpace%20%2B%3D%20childHeight%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E5%B0%86%E6%AD%A4%20childView%20%E7%9A%84%20childHeight%20%E5%8A%A0%E5%85%A5%E5%88%B0%20mTotalLength%20%E4%B8%AD%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E5%B9%B6%E5%8A%A0%E4%B8%8A%20childView%20%E7%9A%84%20topMargin%20%E5%92%8C%20bottomMargin%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20getNextLocationOffset%20%E6%96%B9%E6%B3%95%E8%BF%94%E5%9B%9E%200%EF%BC%8C%E6%96%B9%E4%BE%BF%E4%BB%A5%E5%90%8E%E6%89%A9%E5%B1%95%E4%BD%BF%E7%94%A8%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20int%20totalLength%20%3D%20mTotalLength%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mTotalLength%20%3D%20Math.max(totalLength%2C%20totalLength%20%2B%20childHeight%20%2B%20lp.topMargin%20%2B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lp.bottomMargin%20%2B%20getNextLocationOffset(child))%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(useLargestChild)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20largestChildHeight%20%3D%20Math.max(childHeight%2C%20largestChildHeight)%3B%2F%2F%E8%AE%B0%E5%BD%95%E6%9C%80%E5%A4%A7%E5%AD%90view%E9%AB%98%E5%BA%A6%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E4%B8%8B%E9%9D%A2%E4%B8%A4%E4%B8%AA%20if%20%E5%88%A4%E6%96%AD%E9%83%BD%E5%92%8C%20%60android%3AbaselineAlignedChildIndex%60%20%E5%B1%9E%E6%80%A7%E6%9C%89%E5%85%B3%2C%E8%BF%99%E9%87%8C%E4%B8%8D%E5%B1%95%E5%BC%80%E5%88%86%E6%9E%90%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20If%20applicable%2C%20compute%20the%20additional%20offset%20to%20the%20child's%20baseline%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20we'll%20need%20later%20when%20asked%20%7B%40link%20%23getBaseline%7D.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20((baselineChildIndex%20%3E%3D%200)%20%26%26%20(baselineChildIndex%20%3D%3D%20i%20%2B%201))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mBaselineChildTop%20%3D%20mTotalLength%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20if%20we%20are%20trying%20to%20use%20a%20child%20index%20for%20our%20baseline%2C%20the%20above%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20book%20keeping%20only%20works%20if%20there%20are%20no%20children%20above%20it%20with%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20weight.%20%20fail%20fast%20to%20aid%20the%20developer.%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(i%20%3C%20baselineChildIndex%20%26%26%20lp.weight%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20throw%20new%20RuntimeException(%22A%20child%20of%20LinearLayout%20with%20index%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2B%20%22less%20than%20mBaselineAlignedChildIndex%20has%20weight%20%3E%200%2C%20which%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2B%20%22won't%20work.%20%20Either%20remove%20the%20weight%2C%20or%20don't%20set%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2B%20%22mBaselineAlignedChildIndex.%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20boolean%20matchWidthLocally%20%3D%20false%3B%2F%2F%E8%AF%A5%E5%AD%90view%E6%98%AF%E5%90%A6%E9%9C%80%E8%A6%81%E6%B5%8B%E9%87%8F%E5%AE%BD%E5%BA%A6%0A%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E6%89%80%E6%9C%89%20widthMode%20%E6%98%AF%20%60MeasureSpec.EXACTLY%60%EF%BC%8C%E4%B8%8D%E4%BC%9A%E8%BF%9B%E5%85%A5%E6%AD%A4%20if%20%E5%88%A4%E6%96%AD%20%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(widthMode%20!%3D%20MeasureSpec.EXACTLY%20%26%26%20lp.width%20%3D%3D%20LayoutParams.MATCH_PARENT)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20The%20width%20of%20the%20linear%20layout%20will%20scale%2C%20and%20at%20least%20one%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20child%20said%20it%20wanted%20to%20match%20our%20width.%20Set%20a%20flag%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20indicating%20that%20we%20need%20to%20remeasure%20at%20least%20that%20view%20when%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20we%20know%20our%20width.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E5%BD%93%E7%88%B6%E7%B1%BB%EF%BC%88LinearLayout%EF%BC%89%E4%B8%8D%E6%98%AFmatch_parent%E6%88%96%E8%80%85%E7%B2%BE%E7%A1%AE%E5%80%BC%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E4%BD%86%E5%AD%90%E6%8E%A7%E4%BB%B6%E5%8D%B4%E6%98%AF%E4%B8%80%E4%B8%AAmatch_parent%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E9%82%A3%E4%B9%88matchWidthLocally%E5%92%8CmatchWidth%E7%BD%AE%E4%B8%BAtrue%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E6%84%8F%E5%91%B3%E7%9D%80%E8%BF%99%E4%B8%AA%E6%8E%A7%E4%BB%B6%E5%B0%86%E4%BC%9A%E5%8D%A0%E6%8D%AE%E7%88%B6%E7%B1%BB%EF%BC%88%E6%B0%B4%E5%B9%B3%E6%96%B9%E5%90%91%EF%BC%89%E7%9A%84%E6%89%80%E6%9C%89%E7%A9%BA%E9%97%B4%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20matchWidth%20%3D%20true%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20matchWidthLocally%20%3D%20true%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E8%AE%A1%E7%AE%97%E4%B8%89%E4%B8%AA%E5%92%8C%E5%AE%BD%E5%BA%A6%E7%9B%B8%E5%85%B3%E7%9A%84%E5%8F%98%E9%87%8F%E5%80%BC%0A%20%20%20%20%20%20%20%20%20%20%20%20final%20int%20margin%20%3D%20lp.leftMargin%20%2B%20lp.rightMargin%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20final%20int%20measuredWidth%20%3D%20child.getMeasuredWidth()%20%2B%20margin%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20maxWidth%20%3D%20Math.max(maxWidth%2C%20measuredWidth)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20childState%20%3D%20combineMeasuredStates(childState%2C%20child.getMeasuredState())%3B%2F%2F%E8%8E%B7%E5%8F%96%E5%AD%90viewmeasure%E5%90%8E%E7%9A%84state%E7%8A%B6%E6%80%81%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20allFillParent%20%3D%20allFillParent%20%26%26%20lp.width%20%3D%3D%20LayoutParams.MATCH_PARENT%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(lp.weight%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%E9%9C%80%E8%A6%81%E8%AE%A1%E7%AE%97%E6%9D%83%E9%87%8D%E7%9A%84%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F*%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20Widths%20of%20weighted%20Views%20are%20bogus%20if%20we%20end%20up%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20remeasuring%2C%20so%20keep%20them%20separate.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%20alternative%20%E5%8F%AF%E4%BE%9B%E9%80%89%E6%8B%A9%E7%9A%84%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20weightedMaxWidth%20%3D%20Math.max(weightedMaxWidth%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20matchWidthLocally%20%3F%20margin%20%3A%20measuredWidth)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%E5%A6%82%E6%9E%9C%E4%B8%8D%E9%9C%80%E8%A6%81%E8%AE%A1%E7%AE%97%E6%9D%83%E9%87%8D%E8%B5%B0%E8%BF%99%E9%87%8C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20alternativeMaxWidth%20%3D%20Math.max(alternativeMaxWidth%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20matchWidthLocally%20%3F%20margin%20%3A%20measuredWidth)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20i%20%2B%3D%20getChildrenSkipCount(child%2C%20i)%3B%0A%20%20%20%20%20%20%20%20%7D%2F%2Ffor%E5%BE%AA%E7%8E%AF%E7%BB%93%E6%9D%9F%0A%0A%20%20%20%20%20%20%20%2F%2F%20%E5%A6%82%E6%9E%9C%E5%AD%98%E5%9C%A8%E6%B2%A1%E6%9C%89%E8%B7%B3%E8%BF%87%E7%9A%84%20childView%20%E5%B9%B6%E4%B8%94%E9%9C%80%E8%A6%81%E7%BB%98%E5%88%B6%20end%20divider%20%E5%88%99%E9%9C%80%E8%A6%81%E5%8A%A0%E4%B8%8A%20end%20%E4%BD%8D%E7%BD%AE%E7%9A%84%20divider%20%E7%9A%84%E9%AB%98%E5%BA%A6%0A%20%20%20%20%20%20%20%20if%20(nonSkippedChildCount%20%3E%200%20%26%26%20hasDividerBeforeChildAt(count))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20mTotalLength%20%2B%3D%20mDividerHeight%3B%0A%20%20%20%20%20%20%20%20%7D%0A%60%60%60%0A%0A%23%23%23%23%23%23%20measureChildBeforeLayout()%0A%E5%9C%A8%E6%AD%A4%E6%96%B9%E6%B3%95%E4%B8%AD%E5%B0%86%E4%BC%9A%E8%AE%A1%E7%AE%97%E6%AF%8F%E4%B8%AA%20childView%20%E7%9A%84%E5%A4%A7%E5%B0%8F%2C%E8%B0%83%E7%94%A8%20ViewGroup%20%E7%9A%84%20measureChildWithMargins()%20%E6%96%B9%E6%B3%95%E8%AE%A1%E7%AE%97%E6%AF%8F%E4%B8%AA%20childView%20%E7%9A%84%E5%A4%A7%E5%B0%8F%EF%BC%8C%E5%9C%A8%E6%B5%8B%E9%87%8F%E5%9E%82%E7%9B%B4%E6%96%B9%E5%90%91%E7%9A%84%20childView%20%E6%97%B6%EF%BC%8C%E6%9C%89%E4%B8%80%E4%B8%AA%E9%9D%9E%E5%B8%B8%E9%87%8D%E8%A6%81%E7%9A%84%E5%8F%82%E6%95%B0%E9%9C%80%E8%A6%81%E6%B3%A8%E6%84%8F%EF%BC%8C%E5%8D%B3%EF%BC%9AheightUsed%EF%BC%8C%E6%A0%B9%E6%8D%AE%E8%8B%B1%E6%96%87%E6%B3%A8%E9%87%8A%EF%BC%8CheightUsed%20%E6%98%AF%E6%8C%87%E5%9C%A8%E5%9E%82%E7%9B%B4%E6%96%B9%E5%90%91%EF%BC%8C%E5%B7%B2%E7%BB%8F%E8%A2%AB%20parentView%20%E6%88%96%E8%80%85%20parentView%20%E7%9A%84%E5%85%B6%E4%BB%96%20childView%20%E4%BD%BF%E7%94%A8%E4%BA%86%E7%9A%84%E7%A9%BA%E9%97%B4%0A%0A%60%60%60java%0Avoid%20measureChildBeforeLayout(View%20child%2C%20int%20childIndex%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20int%20widthMeasureSpec%2C%20int%20totalWidth%2C%20int%20heightMeasureSpec%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20int%20totalHeight)%20%7B%0A%20%20%20%20%20%20%20%20measureChildWithMargins(child%2C%20widthMeasureSpec%2C%20totalWidth%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20heightMeasureSpec%2C%20totalHeight)%3B%0A%20%20%20%20%7D%0A%60%60%60%0A%0A%0A%23%23%23%23%23%23%20%E7%AC%AC%E4%BA%8C%E6%AC%A1%E6%B5%8B%E9%87%8F%0A%E5%A6%82%E6%9E%9C%E8%BF%9B%E5%85%A5%E8%BF%99%E4%B8%AA%20if%20%E6%9D%A1%E4%BB%B6%EF%BC%8C%E4%BC%9A%E8%BF%9B%E8%A1%8C%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%9A%84%20for%20%E5%BE%AA%E7%8E%AF%E9%81%8D%E5%8E%86%20childView%EF%BC%8C%E9%87%8D%E6%96%B0%E8%AE%A1%E7%AE%97%C2%A0mTotalLength%0A%0A%60%60%60java%0Avoid%20measureVertical(int%20widthMeasureSpec%2C%20int%20heightMeasureSpec)%20%7B%0A%2F%2F%E6%8E%A5%E4%B8%8A%E9%9D%A2%E4%BB%A3%E7%A0%81%0Aif%20(useLargestChild%20%26%26%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(heightMode%20%3D%3D%20MeasureSpec.AT_MOST%20%7C%7C%20heightMode%20%3D%3D%20MeasureSpec.UNSPECIFIED))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20mTotalLength%20%3D%200%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%E9%87%8D%E6%96%B0%E8%AE%A1%E7%AE%97%E6%80%BB%E9%AB%98%E5%BA%A6%3A%E6%AF%8F%E4%B8%AA%E9%9D%9Egone%E7%9A%84view%E7%9A%84%E9%AB%98%E5%BA%A6%E9%83%BD%E6%8C%89%20%E4%B8%8A%E6%AC%A1%E5%BE%AA%E7%8E%AF%E8%AE%B0%E5%BD%95%E7%9A%84%E6%9C%80%E5%A4%A7%E5%AD%90view%E7%9A%84%E9%AB%98%E5%BA%A6%E8%AE%A1%E7%AE%97%2C%E5%86%8D%E5%8A%A0%E4%B8%8Amargin%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(int%20i%20%3D%200%3B%20i%20%3C%20count%3B%20%2B%2Bi)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20View%20child%20%3D%20getVirtualChildAt(i)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(child%20%3D%3D%20null)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mTotalLength%20%2B%3D%20measureNullChild(i)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(child.getVisibility()%20%3D%3D%20GONE)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20i%20%2B%3D%20getChildrenSkipCount(child%2C%20i)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20LinearLayout.LayoutParams%20lp%20%3D%20(LinearLayout.LayoutParams)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20child.getLayoutParams()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Account%20for%20negative%20margins%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20int%20totalLength%20%3D%20mTotalLength%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mTotalLength%20%3D%20Math.max(totalLength%2C%20totalLength%20%2B%20largestChildHeight%20%2B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lp.topMargin%20%2B%20lp.bottomMargin%20%2B%20getNextLocationOffset(child))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%60%60%60%0A%0A%23%23%23%23%23%23%20%20%E6%B5%8B%E9%87%8F%E7%AC%AC%E4%B8%89%E9%98%B6%E6%AE%B5%0A%E9%92%88%E5%AF%B9%E8%AE%BE%E7%BD%AE%E4%BA%86%C2%A0android%3Alayout_weight%C2%A0%E5%B1%9E%E6%80%A7%E7%9A%84%E5%B8%83%E5%B1%80%EF%BC%8C%E9%87%8D%E6%96%B0%E8%AE%A1%E7%AE%97%C2%A0mTotalLength%0A%0A%60%60%60java%0Avoid%20measureVertical(int%20widthMeasureSpec%2C%20int%20heightMeasureSpec)%20%7B%0A%2F%2F%E6%8E%A5%E4%B8%8A%E9%9D%A2%E4%BB%A3%E7%A0%81%0A%20%20%20%20%20%20%20%20%2F%2F%20Add%20in%20our%20padding%0A%20%20%20%20%20%20%20%20mTotalLength%20%2B%3D%20mPaddingTop%20%2B%20mPaddingBottom%3B%0A%0A%20%20%20%20%20%20%20%20int%20heightSize%20%3D%20mTotalLength%3B%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Check%20against%20our%20minimum%20height%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%2F%2F%20%E9%80%9A%E8%BF%87%20getSuggestedMinimumHeight()%20%E5%BE%97%E5%88%B0%E5%BB%BA%E8%AE%AE%E6%9C%80%E5%B0%8F%E9%AB%98%E5%BA%A6%EF%BC%8C%E5%B9%B6%E5%92%8C%E8%AE%A1%E7%AE%97%E5%BE%97%E5%88%B0%E7%9A%84%0A%20%20%20%20%20%20%20%20%2F%2F%20mTotalLength%20%E6%AF%94%E8%BE%83%E5%8F%96%E6%9C%80%E5%A4%A7%E5%80%BC%0A%20%20%20%20%20%20%20%20heightSize%20%3D%20Math.max(heightSize%2C%20getSuggestedMinimumHeight())%3B%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Reconcile%20our%20calculated%20size%20with%20the%20heightMeasureSpec%0A%20%20%20%20%20%20%20%2F%2F%20%E9%80%9A%E8%BF%87%20heightMeasureSpec%EF%BC%8C%E8%B0%83%E6%95%B4%20heightSize%20%E7%9A%84%E5%A4%A7%E5%B0%8F%0A%20%20%20%20%20%20%20%20int%20heightSizeAndState%20%3D%20resolveSizeAndState(heightSize%2C%20heightMeasureSpec%2C%200)%3B%0A%20%20%20%20%20%20%20%20heightSize%20%3D%20heightSizeAndState%20%26%20MEASURED_SIZE_MASK%3B%0A%20%20%20%20%20%20%20%20%2F%2F%20Either%20expand%20children%20with%20weight%20to%20take%20up%20available%20space%20or%0A%20%20%20%20%20%20%20%20%2F%2F%20shrink%20them%20if%20they%20extend%20beyond%20our%20current%20bounds.%20If%20we%20skipped%0A%20%20%20%20%20%20%20%20%2F%2F%20measurement%20on%20any%20children%2C%20we%20need%20to%20measure%20them%20now.%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%2F%2F%20%E9%87%8D%E6%96%B0%E8%AE%A1%E7%AE%97%E6%9C%89%20weight%20%E5%B1%9E%E6%80%A7%E7%9A%84%20childView%20%E5%A4%A7%E5%B0%8F%EF%BC%8C%0A%20%20%20%20%20%20%20%20%2F%2F%20%E5%A6%82%E6%9E%9C%E8%BF%98%E6%9C%89%E5%8F%AF%E7%94%A8%E7%9A%84%E7%A9%BA%E9%97%B4%EF%BC%8C%E5%88%99%E6%89%A9%E5%B1%95%20childView%EF%BC%8C%E8%AE%A1%E7%AE%97%E5%85%B6%E5%A4%A7%E5%B0%8F%0A%20%20%20%20%20%20%20%20%2F%2F%20%E5%A6%82%E6%9E%9C%20childView%20%E8%B6%85%E5%87%BA%E4%BA%86%20LinearLayout%20%E7%9A%84%E8%BE%B9%E7%95%8C%EF%BC%8C%E5%88%99%E6%94%B6%E7%BC%A9%20childView%0A%20%20%20%20%20%20%20%20int%20remainingExcess%20%3D%20heightSize%20-%20mTotalLength%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2B%20(mAllowInconsistentMeasurement%20%3F%200%20%3A%20consumedExcessSpace)%3B%0A%20%20%20%20%20%20%20%20if%20(skippedMeasure%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%7C%20((sRemeasureWeightedChildren%20%7C%7C%20remainingExcess%20!%3D%200)%20%26%26%20totalWeight%20%3E%200.0f))%20%7B%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E6%A0%B9%E6%8D%AE%20mWeightSum%20%E8%AE%A1%E7%AE%97%E5%BE%97%E5%88%B0%20remainingWeightSum%EF%BC%8CmWeightSum%20%E6%98%AF%E9%80%9A%E8%BF%87%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%60android%3AweightSum%60%20%E5%B1%9E%E6%80%A7%E8%AE%BE%E7%BD%AE%E7%9A%84%EF%BC%8CtotalWeight%20%E6%98%AF%E9%80%9A%E8%BF%87%E7%AC%AC%E4%B8%80%E6%AC%A1%20for%20%E5%BE%AA%E7%8E%AF%E8%AE%A1%E7%AE%97%E5%BE%97%E5%88%B0%E7%9A%84%0A%20%20%20%20%20%20%20%20%20%20%20%20float%20remainingWeightSum%20%3D%20mWeightSum%20%3E%200.0f%20%3F%20mWeightSum%20%3A%20totalWeight%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E5%B0%86%20mTotalLength%20%E5%A4%8D%E4%BD%8D%E4%B8%BA%200%0A%20%20%20%20%20%20%20%20%20%20%20%20mTotalLength%20%3D%200%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E6%9D%83%E9%87%8Dchildview%E7%9A%84%E6%B5%8B%E9%87%8F%EF%BC%8C%E5%BC%80%E5%A7%8B%E7%9C%9F%E6%AD%A3%E7%9A%84%E7%AC%AC%E4%BA%8C%E6%AC%A1%20for%20%E5%BE%AA%E7%8E%AF%E9%81%8D%E5%8E%86%E6%AF%8F%E4%B8%80%E4%B8%AA%20childView%EF%BC%8C%E9%87%8D%E6%96%B0%E6%B5%8B%E9%87%8F%E6%AF%8F%E4%B8%80%E4%B8%AA%20childView%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(int%20i%20%3D%200%3B%20i%20%3C%20count%3B%20%2B%2Bi)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20View%20child%20%3D%20getVirtualChildAt(i)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(child%20%3D%3D%20null%20%7C%7C%20child.getVisibility()%20%3D%3D%20View.GONE)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20LayoutParams%20lp%20%3D%20(LayoutParams)%20child.getLayoutParams()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20float%20childWeight%20%3D%20lp.weight%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E5%A6%82%E6%9E%9C%E8%AF%A5%20childView%20%E8%AE%BE%E7%BD%AE%E4%BA%86%20%60weight%60%20%E5%80%BC%EF%BC%8C%E5%88%99%E8%BF%9B%E5%85%A5%20if%20%E8%AF%AD%E5%8F%A5%E5%9D%97%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(childWeight%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E8%BF%99%E6%98%AF%E8%AE%BE%E7%BD%AE%E4%BA%86%20weight%20%E7%9A%84%E6%83%85%E5%86%B5%E4%B8%8B%EF%BC%8C%E6%9C%80%E9%87%8D%E8%A6%81%E7%9A%84%E4%B8%80%E8%A1%8C%E4%BB%A3%E7%A0%81%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20remainingExcess%20%E5%89%A9%E4%BD%99%E9%AB%98%E5%BA%A6%20*%20(%20childView%20%E7%9A%84%20weight%20%2F%20remainingWeightSum)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20share%20%E4%BE%BF%E6%98%AF%E6%AD%A4%20childView%20%E9%80%9A%E8%BF%87%E8%BF%99%E4%B8%AA%E5%85%AC%E5%BC%8F%E8%AE%A1%E7%AE%97%E5%BE%97%E5%88%B0%E7%9A%84%E9%AB%98%E5%BA%A6%EF%BC%8C%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E5%B9%B6%E9%87%8D%E6%96%B0%E8%AE%A1%E7%AE%97%E5%89%A9%E4%BD%99%E9%AB%98%E5%BA%A6%20remainingExcess%20%E5%92%8C%E5%89%A9%E4%BD%99%E6%9D%83%E9%87%8D%E6%80%BB%E5%92%8C%20remainingWeightSum%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20int%20share%20%3D%20(int)%20(childWeight%20*%20remainingExcess%20%2F%20remainingWeightSum)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20remainingExcess%20-%3D%20share%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20remainingWeightSum%20-%3D%20childWeight%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E9%80%9A%E8%BF%87%E4%B8%8B%E9%9D%A2%E7%9A%84%20if%20%E6%9D%A1%E4%BB%B6%E9%87%8D%E6%96%B0%E8%AE%A1%E7%AE%97%EF%BC%8CchildHeight%20%E6%98%AF%E6%9C%80%E7%BB%88%20childView%20%E7%9A%84%E7%9C%9F%E6%AD%A3%E9%AB%98%E5%BA%A6%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20int%20childHeight%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(mUseLargestChild%20%26%26%20heightMode%20!%3D%20MeasureSpec.EXACTLY)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20childHeight%20%3D%20largestChildHeight%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(lp.height%20%3D%3D%200%20%26%26%20(!mAllowInconsistentMeasurement%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%7C%20heightMode%20%3D%3D%20MeasureSpec.EXACTLY))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20This%20child%20needs%20to%20be%20laid%20out%20from%20scratch%20using%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20only%20its%20share%20of%20excess%20space.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20childHeight%20%3D%20share%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20This%20child%20had%20some%20intrinsic%20height%20to%20which%20we%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20need%20to%20add%20its%20share%20of%20excess%20space.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20childHeight%20%3D%20child.getMeasuredHeight()%20%2B%20share%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E8%AE%A1%E7%AE%97%20childHeightMeasureSpec%20%26%20childWidthMeasureSpec%EF%BC%8C%E5%B9%B6%E8%B0%83%E7%94%A8%20child.measure()%20%E6%96%B9%E6%B3%95%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20int%20childHeightMeasureSpec%20%3D%20MeasureSpec.makeMeasureSpec(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20Math.max(0%2C%20childHeight)%2C%20MeasureSpec.EXACTLY)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20int%20childWidthMeasureSpec%20%3D%20getChildMeasureSpec(widthMeasureSpec%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mPaddingLeft%20%2B%20mPaddingRight%20%2B%20lp.leftMargin%20%2B%20lp.rightMargin%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lp.width)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20child.measure(childWidthMeasureSpec%2C%20childHeightMeasureSpec)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Child%20may%20now%20not%20fit%20in%20vertical%20dimension.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20childState%20%3D%20combineMeasuredStates(childState%2C%20child.getMeasuredState()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%26%20(MEASURED_STATE_MASK%3E%3EMEASURED_HEIGHT_STATE_SHIFT))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20int%20margin%20%3D%20%20lp.leftMargin%20%2B%20lp.rightMargin%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20int%20measuredWidth%20%3D%20child.getMeasuredWidth()%20%2B%20margin%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20maxWidth%20%3D%20Math.max(maxWidth%2C%20measuredWidth)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20boolean%20matchWidthLocally%20%3D%20widthMode%20!%3D%20MeasureSpec.EXACTLY%20%26%26%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lp.width%20%3D%3D%20LayoutParams.MATCH_PARENT%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20alternativeMaxWidth%20%3D%20Math.max(alternativeMaxWidth%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20matchWidthLocally%20%3F%20margin%20%3A%20measuredWidth)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20allFillParent%20%3D%20allFillParent%20%26%26%20lp.width%20%3D%3D%20LayoutParams.MATCH_PARENT%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E8%80%83%E8%99%91%20childView.topMargin%20%26%20childView.bottomMargin%EF%BC%8C%E9%87%8D%E6%96%B0%E8%AE%A1%E7%AE%97%20mTotalLength%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20int%20totalLength%20%3D%20mTotalLength%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mTotalLength%20%3D%20Math.max(totalLength%2C%20totalLength%20%2B%20child.getMeasuredHeight()%20%2B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lp.topMargin%20%2B%20lp.bottomMargin%20%2B%20getNextLocationOffset(child))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Add%20in%20our%20padding%0A%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E5%AE%8C%E6%88%90%20for%20%E5%BE%AA%E7%8E%AF%E4%B9%8B%E5%90%8E%EF%BC%8C%E5%8A%A0%E5%85%A5%20LinearLayout%20%E6%9C%AC%E8%BA%AB%E7%9A%84%20mPaddingTop%20%26%20mPaddingBottom%0A%20%20%20%20%20%20%20%20%20%20%20%20mTotalLength%20%2B%3D%20mPaddingTop%20%2B%20mPaddingBottom%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20TODO%3A%20Should%20we%20recompute%20the%20heightSpec%20based%20on%20the%20new%20total%20length%3F%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%E9%87%8D%E6%96%B0%E8%AE%A1%E7%AE%97%20alternativeMaxWidth%0A%20%20%20%20%20%20%20%20%20%20%20%20alternativeMaxWidth%20%3D%20Math.max(alternativeMaxWidth%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20weightedMaxWidth)%3B%0A%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20We%20have%20no%20limit%2C%20so%20make%20all%20weighted%20views%20as%20tall%20as%20the%20largest%20child.%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Children%20will%20have%20already%20been%20measured%20once.%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(useLargestChild%20%26%26%20heightMode%20!%3D%20MeasureSpec.EXACTLY)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20(int%20i%20%3D%200%3B%20i%20%3C%20count%3B%20i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20View%20child%20%3D%20getVirtualChildAt(i)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(child%20%3D%3D%20null%20%7C%7C%20child.getVisibility()%20%3D%3D%20View.GONE)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20final%20LinearLayout.LayoutParams%20lp%20%3D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20(LinearLayout.LayoutParams)%20child.getLayoutParams()%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20float%20childExtra%20%3D%20lp.weight%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(childExtra%20%3E%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20child.measure(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20MeasureSpec.makeMeasureSpec(child.getMeasuredWidth()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20MeasureSpec.EXACTLY)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20MeasureSpec.makeMeasureSpec(largestChildHeight%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20MeasureSpec.EXACTLY))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20if%20(!allFillParent%20%26%26%20widthMode%20!%3D%20MeasureSpec.EXACTLY)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20maxWidth%20%3D%20alternativeMaxWidth%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20%E8%B0%83%E6%95%B4%20width%20%E5%A4%A7%E5%B0%8F%0A%20%20%20%20%20%20%20%20maxWidth%20%2B%3D%20mPaddingLeft%20%2B%20mPaddingRight%3B%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Check%20against%20our%20minimum%20width%0A%20%20%20%20%20%20%20%20maxWidth%20%3D%20Math.max(maxWidth%2C%20getSuggestedMinimumWidth())%3B%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20%E8%B0%83%E7%94%A8%20setMeasuredDimension()%20%E8%AE%BE%E7%BD%AE%20LinearLayout%20%E7%9A%84%E5%A4%A7%E5%B0%8F%0A%20%20%20%20%20%20%20%20setMeasuredDimension(resolveSizeAndState(maxWidth%2C%20widthMeasureSpec%2C%20childState)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20heightSizeAndState)%3B%0A%0A%20%20%20%20%20%20%20%20%2F%2F%E6%9C%80%E5%90%8E%EF%BC%8C%E8%AE%BE%E7%BD%AELinearLayout%E7%9A%84size%E5%A4%A7%E5%B0%8F%E5%92%8C%E7%8A%B6%E6%80%81%EF%BC%8C%E5%A6%82%E6%9E%9CLinearLayout%E6%9C%89%E8%AE%BE%E7%BD%AEwidth%E4%B8%BAmatch_parent%E7%9A%84%E8%AF%9D%EF%BC%8C%E5%B0%86%E4%BC%9A%E8%B0%83%E7%94%A8forceUniformWidth%E5%86%8D%E6%B5%8B%E9%87%8F%E4%B8%80%E6%AC%A1%E6%89%80%E6%9C%89%E7%9A%84subchild%EF%BC%8C%E8%BF%99%E9%87%8C%E4%B8%BB%E8%A6%81%E6%98%AF%E6%B5%8B%E9%87%8Fsubchild%E7%9A%84width%E5%A4%A7%E5%B0%8F%0A%20%20%20%20%20%20%20%20if%20(matchWidth)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20forceUniformWidth(count%2C%20heightMeasureSpec)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%60%60%60%0A%0A%E5%81%87%E5%A6%82%E4%B8%80%E5%85%B1%E6%9C%893%E4%B8%AAsubchild%E4%B8%94%E9%83%BD%E6%9C%89%E8%AE%BE%E7%BD%AEweight%20%EF%BC%8C%E5%88%86%E5%88%AB%E4%B8%BA3%E3%80%812%E3%80%811%EF%BC%8C%E6%88%91%E4%BB%AC%E5%81%87%E8%AE%BE%E5%89%A9%E4%BD%99%E7%9A%84space%E4%B8%BA120%EF%BC%8C%E5%88%99%E7%AC%AC%E4%B8%80%E4%B8%AAview%E7%9A%84%E5%A4%A7%E5%B0%8F%E4%B8%BA120%20*%203%2F%EF%BC%883%2B2%2B1%EF%BC%89%3D60%EF%BC%8C%E7%AC%AC%E4%BA%8C%E4%B8%AAview%E7%9A%84%E5%A4%A7%E5%B0%8F%E4%B8%BA%EF%BC%88120-60%EF%BC%89*2%2F%EF%BC%882%2B1%EF%BC%89%3D40%EF%BC%8C%E7%AC%AC3%E4%B8%AAview%E7%9A%84%E5%A4%A7%E5%B0%8F%E4%B8%BA%EF%BC%8860-40%EF%BC%89*1%2F1%20%3D%2020%0A%0A%23%23%23%23%23%23%20resolveSizeAndState%0A%60%60%60java%0Apublic%20static%20int%20resolveSizeAndState(int%20size%2C%20int%20measureSpec%2C%20int%20childMeasuredState)%20%7B%0A%20%20%20%20%20%20%20%20final%20int%20specMode%20%3D%20MeasureSpec.getMode(measureSpec)%3B%0A%20%20%20%20%20%20%20%20final%20int%20specSize%20%3D%20MeasureSpec.getSize(measureSpec)%3B%0A%20%20%20%20%20%20%20%20final%20int%20result%3B%0A%20%20%20%20%20%20%20%20switch%20(specMode)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20MeasureSpec.AT_MOST%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(specSize%20%3C%20size)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result%20%3D%20specSize%20%7C%20MEASURED_STATE_TOO_SMALL%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result%20%3D%20size%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20MeasureSpec.EXACTLY%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result%20%3D%20specSize%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20MeasureSpec.UNSPECIFIED%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20default%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20result%20%3D%20size%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20result%20%7C%20(childMeasuredState%20%26%20MEASURED_STATE_MASK)%3B%0A%20%20%20%20%7D%0A%60%60%60%0A%0A%23%23%23%23%23%23%20%E6%80%BB%E7%BB%93%0A1.%20LinearLayout%E9%92%88%E5%AF%B9%E8%AE%BE%E7%BD%AEweight%E4%B8%8E%E4%B8%8D%E8%AE%BE%E7%BD%AEweight%E7%9A%84%E6%83%85%E5%86%B5%E5%88%86%E5%88%AB%E5%A4%84%E7%90%86%C2%A0%0A2.%20%E5%9C%A8%20LinearLayout%20%E4%B8%AD%E6%80%BB%E5%85%B1%E6%9C%89%203%20%E4%B8%AA%20for%20%E5%BE%AA%E7%8E%AF%EF%BC%8C%E5%88%86%E5%88%AB%E5%A4%84%E7%90%86%E4%B8%8D%E5%90%8C%E7%9A%84%E6%B5%81%E7%A8%8B%0A%20%20%20%20-%20%E7%AC%AC%E4%B8%80%E4%B8%AA%20for%20%E5%BE%AA%E7%8E%AF%EF%BC%8C%E5%8F%AA%E4%BC%9A%E5%9C%A8%E4%B8%8D%E4%BD%BF%E7%94%A8%20weight%20%E5%B1%9E%E6%80%A7%E6%97%B6%E8%BF%9B%E5%85%A5%EF%BC%8C%E5%B9%B6%E6%9C%89%E5%8F%AF%E8%83%BD%E4%BC%9A%E6%B5%8B%E9%87%8F%E6%AF%8F%E4%B8%AA%20childView%20%E7%9A%84%E5%A4%A7%E5%B0%8F%0A%20%20%20%20-%20%E7%AC%AC%E4%BA%8C%E4%B8%AA%20for%20%E5%BE%AA%E7%8E%AF%EF%BC%8C%E5%9C%A8%E4%BD%BF%E7%94%A8%20android%3AmeasureWithLargestChild%20%E6%97%B6%E6%89%8D%E4%BC%9A%E8%BF%9B%E5%85%A5%EF%BC%8C%E5%B9%B6%E4%B8%94%E5%8D%B3%E4%BD%BF%E8%BF%9B%E5%85%A5%E4%B9%9F%E4%B8%8D%E4%BC%9A%E8%B0%83%E7%94%A8%20childView%20%E7%9A%84%E6%B5%8B%E9%87%8F%E6%96%B9%E6%B3%95%EF%BC%8C%E5%8F%AA%E4%BC%9A%E6%9B%B4%E6%96%B0%20mTotalLength%20%E5%8F%98%E9%87%8F%0A%20%20%20%20-%20%E7%AC%AC%E4%B8%89%E4%B8%AA%20for%20%E5%BE%AA%E7%8E%AF%EF%BC%8C%E5%8F%AA%E4%BC%9A%E5%9C%A8%E4%BD%BF%E7%94%A8%20weight%20%E5%B1%9E%E6%80%A7%E6%97%B6%E8%BF%9B%E5%85%A5%EF%BC%8C%E5%B9%B6%E6%B5%8B%E9%87%8F%E6%AF%8F%E4%B8%AA%20childView%20%E7%9A%84%E5%A4%A7%E5%B0%8F%0A%0A%0A%23%23%23%20%E8%87%AA%E5%AE%9A%E4%B9%89View%E6%80%BB%E7%BB%93%0A%0A%23%23%23%23%20%E8%87%AA%E5%AE%9A%E4%B9%89UI%E5%9F%BA%E7%A1%80%0A1.%20Android%E7%9A%84%E5%9D%90%E6%A0%87%E7%B3%BB%0A%0A!%5Bdfd2c7d5c1b14553ade958dcee6e45b1.png%5D(en-resource%3A%2F%2Fdatabase%2F627%3A0)%0A!%5B26a12c6933b4cfd2fdb52f178ea0b701.png%5D(en-resource%3A%2F%2Fdatabase%2F629%3A0)%0A!%5Bd5a7335dfa20a20387585cb421ab7111.png%5D(en-resource%3A%2F%2Fdatabase%2F631%3A0)%0A%0A-%20View%E7%9A%84%E9%9D%99%E6%80%81%E5%9D%90%E6%A0%87%E6%96%B9%E6%B3%95%0A%0A%7C%20View%E7%9A%84%E9%9D%99%E6%80%81%E5%9D%90%E6%A0%87%E6%96%B9%E6%B3%95%20%7C%20%E8%A7%A3%E9%87%8A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%7C%20------------------%20%7C%20%3A-----------------------------------------------------------%20%7C%0A%7C%20getLeft()%20%20%20%20%20%20%20%20%20%20%7C%20%E8%BF%94%E5%9B%9EView%E8%87%AA%E8%BA%AB%E5%B7%A6%E8%BE%B9%E5%88%B0%E7%88%B6%E5%B8%83%E5%B1%80%E5%B7%A6%E8%BE%B9%E7%9A%84%E8%B7%9D%E7%A6%BB%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%7C%20getTop()%20%20%20%20%20%20%20%20%20%20%20%7C%20%E8%BF%94%E5%9B%9EView%E8%87%AA%E8%BA%AB%E9%A1%B6%E8%BE%B9%E5%88%B0%E7%88%B6%E5%B8%83%E5%B1%80%E9%A1%B6%E8%BE%B9%E7%9A%84%E8%B7%9D%E7%A6%BB%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%7C%20getRight()%20%20%20%20%20%20%20%20%20%7C%20%E8%BF%94%E5%9B%9EView%E8%87%AA%E8%BA%AB%E5%8F%B3%E8%BE%B9%E5%88%B0%E7%88%B6%E5%B8%83%E5%B1%80%E5%B7%A6%E8%BE%B9%E7%9A%84%E8%B7%9D%E7%A6%BB%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%7C%20getBottom()%20%20%20%20%20%20%20%20%7C%20%E8%BF%94%E5%9B%9EView%E8%87%AA%E8%BA%AB%E5%BA%95%E8%BE%B9%E5%88%B0%E7%88%B6%E5%B8%83%E5%B1%80%E9%A1%B6%E8%BE%B9%E7%9A%84%E8%B7%9D%E7%A6%BB%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%7C%20getX()%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%E8%BF%94%E5%9B%9E%E5%80%BC%E4%B8%BAgetLeft()%2BgetTranslationX()%EF%BC%8C%E5%BD%93setTranslationX()%E6%97%B6getLeft()%E4%B8%8D%E5%8F%98%EF%BC%8CgetX()%E5%8F%98%E3%80%82%20%7C%0A%7C%20getY()%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%E8%BF%94%E5%9B%9E%E5%80%BC%E4%B8%BAgetTop()%2BgetTranslationY()%EF%BC%8C%E5%BD%93setTranslationY()%E6%97%B6getTop()%E4%B8%8D%E5%8F%98%EF%BC%8CgetY()%E5%8F%98%E3%80%82%20%7C%0A%0A%0A-%20%E6%89%8B%E6%8C%87%E8%A7%A6%E6%91%B8%E5%B1%8F%E5%B9%95%E6%97%B6MotionEvent%0A%0A%7C%20MotionEvent%E5%9D%90%E6%A0%87%E6%96%B9%E6%B3%95%20%7C%20%E8%A7%A3%E9%87%8A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%7C%20-------------------%20%7C%20----------------------------------%20%7C%0A%7C%20getX()%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%E5%BD%93%E5%89%8D%E8%A7%A6%E6%91%B8%E4%BA%8B%E4%BB%B6%E8%B7%9D%E7%A6%BB%E5%BD%93%E5%89%8DView%E5%B7%A6%E8%BE%B9%E7%9A%84%E8%B7%9D%E7%A6%BB%20%7C%0A%7C%20getY()%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%E5%BD%93%E5%89%8D%E8%A7%A6%E6%91%B8%E4%BA%8B%E4%BB%B6%E8%B7%9D%E7%A6%BB%E5%BD%93%E5%89%8DView%E9%A1%B6%E8%BE%B9%E7%9A%84%E8%B7%9D%E7%A6%BB%20%7C%0A%7C%20getRawX()%20%20%20%20%20%20%20%20%20%20%20%7C%20%E5%BD%93%E5%89%8D%E8%A7%A6%E6%91%B8%E4%BA%8B%E4%BB%B6%E8%B7%9D%E7%A6%BB%E6%95%B4%E4%B8%AA%E5%B1%8F%E5%B9%95%E5%B7%A6%E8%BE%B9%E7%9A%84%E8%B7%9D%E7%A6%BB%20%7C%0A%7C%20getRawY()%20%20%20%20%20%20%20%20%20%20%20%7C%20%E5%BD%93%E5%89%8D%E8%A7%A6%E6%91%B8%E4%BA%8B%E4%BB%B6%E8%B7%9D%E7%A6%BB%E6%95%B4%E4%B8%AA%E5%B1%8F%E5%B9%95%E9%A1%B6%E8%BE%B9%E7%9A%84%E8%B7%9D%E7%A6%BB%20%7C%0A%0A-%20%E8%8E%B7%E5%8F%96%E5%AE%BD%E9%AB%98%0A%0A%7C%20View%E5%AE%BD%E9%AB%98%E6%96%B9%E6%B3%95%20%20%20%20%20%20%20%20%7C%20%E8%A7%A3%E9%87%8A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%7C%20-------------------%20%7C%20------------------------------------------------------------%20%7C%0A%7C%20getWidth()%20%20%20%20%20%20%20%20%20%20%7C%20layout%E5%90%8E%E6%9C%89%E6%95%88%EF%BC%8C%E8%BF%94%E5%9B%9E%E5%80%BC%E6%98%AFmRight-mLeft%EF%BC%8C%E4%B8%80%E8%88%AC%E4%BC%9A%E5%8F%82%E8%80%83measure%E7%9A%84%E5%AE%BD%E5%BA%A6%EF%BC%88measure%E5%8F%AF%E8%83%BD%E6%B2%A1%E7%94%A8%EF%BC%89%EF%BC%8C%E4%BD%86%E4%B8%8D%E6%98%AF%E5%BF%85%E9%A1%BB%E7%9A%84%E3%80%82%20%7C%0A%7C%20getHeight()%20%20%20%20%20%20%20%20%20%7C%20layout%E5%90%8E%E6%9C%89%E6%95%88%EF%BC%8C%E8%BF%94%E5%9B%9E%E5%80%BC%E6%98%AFmBottom-mTop%EF%BC%8C%E4%B8%80%E8%88%AC%E4%BC%9A%E5%8F%82%E8%80%83measure%E7%9A%84%E9%AB%98%E5%BA%A6%EF%BC%88measure%E5%8F%AF%E8%83%BD%E6%B2%A1%E7%94%A8%EF%BC%89%EF%BC%8C%E4%BD%86%E4%B8%8D%E6%98%AF%E5%BF%85%E9%A1%BB%E7%9A%84%E3%80%82%20%7C%0A%7C%20getMeasuredWidth()%20%20%7C%20%E8%BF%94%E5%9B%9Emeasure%E8%BF%87%E7%A8%8B%E5%BE%97%E5%88%B0%E7%9A%84mMeasuredWidth%E5%80%BC%EF%BC%8C%E4%BE%9Blayout%E5%8F%82%E8%80%83%EF%BC%8C%E6%88%96%E8%AE%B8%E6%B2%A1%E7%94%A8%E3%80%82%20%7C%0A%7C%20getMeasuredHeight()%20%7C%20%E8%BF%94%E5%9B%9Emeasure%E8%BF%87%E7%A8%8B%E5%BE%97%E5%88%B0%E7%9A%84mMeasuredHeight%E5%80%BC%EF%BC%8C%E4%BE%9Blayout%E5%8F%82%E8%80%83%EF%BC%8C%E6%88%96%E8%AE%B8%E6%B2%A1%E7%94%A8%E3%80%82%20%7C%0A%0A%0A-%20%E8%8E%B7%E5%8F%96view%E4%BD%8D%E7%BD%AE%0A%0A%7C%20View%E7%9A%84%E6%96%B9%E6%B3%95%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%E7%BB%93%E8%AE%BA%E6%8F%8F%E8%BF%B0%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%7C%20----------------------%20%7C%20------------------------------------------------------------%20%7C%0A%7C%20getLocalVisibleRect()%20%20%7C%20%E8%8E%B7%E5%8F%96View%E8%87%AA%E8%BA%AB%E5%8F%AF%E8%A7%81%E7%9A%84%E5%9D%90%E6%A0%87%E5%8C%BA%E5%9F%9F%EF%BC%8C%E5%9D%90%E6%A0%87%E4%BB%A5%E8%87%AA%E5%B7%B1%E7%9A%84%E5%B7%A6%E4%B8%8A%E8%A7%92%E4%B8%BA%E5%8E%9F%E7%82%B9(0%2C0)%EF%BC%8C%E5%8F%A6%E4%B8%80%E7%82%B9%E4%B8%BA%E5%8F%AF%E8%A7%81%E5%8C%BA%E5%9F%9F%E5%8F%B3%E4%B8%8B%E8%A7%92%E7%9B%B8%E5%AF%B9%E8%87%AA%E5%B7%B1(0%2C0)%E7%82%B9%E7%9A%84%E5%9D%90%E6%A0%87%EF%BC%8C%E5%85%B6%E5%AE%9EView2%E5%BD%93%E5%89%8Dheight%E4%B8%BA550%EF%BC%8C%E5%8F%AF%E8%A7%81height%E4%B8%BA470%E3%80%82%20%7C%0A%7C%20getGlobalVisibleRect()%20%7C%20%E8%8E%B7%E5%8F%96View%E5%9C%A8%E5%B1%8F%E5%B9%95%E7%BB%9D%E5%AF%B9%E5%9D%90%E6%A0%87%E7%B3%BB%E4%B8%AD%E7%9A%84%E5%8F%AF%E8%A7%86%E5%8C%BA%E5%9F%9F%EF%BC%8C%E5%9D%90%E6%A0%87%E4%BB%A5%E5%B1%8F%E5%B9%95%E5%B7%A6%E4%B8%8A%E8%A7%92%E4%B8%BA%E5%8E%9F%E7%82%B9(0%2C0)%EF%BC%8C%E5%8F%A6%E4%B8%80%E4%B8%AA%E7%82%B9%E4%B8%BA%E5%8F%AF%E8%A7%81%E5%8C%BA%E5%9F%9F%E5%8F%B3%E4%B8%8B%E8%A7%92%E7%9B%B8%E5%AF%B9%E5%B1%8F%E5%B9%95%E5%8E%9F%E7%82%B9(0%2C0)%E7%82%B9%E7%9A%84%E5%9D%90%E6%A0%87%E3%80%82%20%7C%0A%7C%20getLocationOnScreen()%20%20%7C%20%E5%9D%90%E6%A0%87%E6%98%AF%E7%9B%B8%E5%AF%B9%E6%95%B4%E4%B8%AA%E5%B1%8F%E5%B9%95%E8%80%8C%E8%A8%80%EF%BC%8CY%E5%9D%90%E6%A0%87%E4%B8%BAView%E5%B7%A6%E4%B8%8A%E8%A7%92%E5%88%B0%E5%B1%8F%E5%B9%95%E9%A1%B6%E9%83%A8%E7%9A%84%E8%B7%9D%E7%A6%BB%E3%80%82%20%20%7C%0A%7C%20getLocationInWindow()%20%20%7C%20%E5%A6%82%E6%9E%9C%E4%B8%BA%E6%99%AE%E9%80%9AActivity%E5%88%99Y%E5%9D%90%E6%A0%87%E4%B8%BAView%E5%B7%A6%E4%B8%8A%E8%A7%92%E5%88%B0%E5%B1%8F%E5%B9%95%E9%A1%B6%E9%83%A8%EF%BC%88%E6%AD%A4%E6%97%B6Window%E4%B8%8E%E5%B1%8F%E5%B9%95%E4%B8%80%E6%A0%B7%E5%A4%A7%EF%BC%89%EF%BC%9B%E5%A6%82%E6%9E%9C%E4%B8%BA%E5%AF%B9%E8%AF%9D%E6%A1%86%E5%BC%8F%E7%9A%84Activity%E5%88%99Y%E5%9D%90%E6%A0%87%E4%B8%BA%E5%BD%93%E5%89%8DDialog%E6%A8%A1%E5%BC%8FActivity%E7%9A%84%E6%A0%87%E9%A2%98%E6%A0%8F%E9%A1%B6%E9%83%A8%E5%88%B0View%E5%B7%A6%E4%B8%8A%E8%A7%92%E7%9A%84%E8%B7%9D%E7%A6%BB%E3%80%82%20%7C%0A%0A-%20View%E6%BB%91%E5%8A%A8%E7%9B%B8%E5%85%B3%E5%9D%90%E6%A0%87%E7%B3%BB%0A%0AView%E7%9A%84scrollTo()%E5%92%8CscrollBy()%E6%98%AF%E7%94%A8%E4%BA%8E%E6%BB%91%E5%8A%A8View%E4%B8%AD%E7%9A%84%E5%86%85%E5%AE%B9%EF%BC%8C%E8%80%8C%E4%B8%8D%E6%98%AF%E6%94%B9%E5%8F%98View%E7%9A%84%E4%BD%8D%E7%BD%AE%EF%BC%9B%E6%94%B9%E5%8F%98View%E5%9C%A8%E5%B1%8F%E5%B9%95%E4%B8%AD%E7%9A%84%E4%BD%8D%E7%BD%AE%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8offsetLeftAndRight()%E5%92%8CoffsetTopAndBottom()%E6%96%B9%E6%B3%95%EF%BC%8C%E4%BB%96%E4%BC%9A%E5%AF%BC%E8%87%B4getLeft()%E7%AD%89%E5%80%BC%E6%94%B9%E5%8F%98%0A%0A%7C%20View%E7%9A%84%E6%BB%91%E5%8A%A8%E6%96%B9%E6%B3%95%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%20%E6%95%88%E6%9E%9C%E5%8F%8A%E6%8F%8F%E8%BF%B0%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%7C%20------------------------------%20%7C%20------------------------------------------------------------%20%7C%0A%7C%20offsetLeftAndRight(int%20offset)%20%7C%20%E6%B0%B4%E5%B9%B3%E6%96%B9%E5%90%91%E6%8C%AA%E5%8A%A8View%EF%BC%8Coffset%E4%B8%BA%E6%AD%A3%E5%88%99x%E8%BD%B4%E6%AD%A3%E5%90%91%E7%A7%BB%E5%8A%A8%EF%BC%8C%E7%A7%BB%E5%8A%A8%E7%9A%84%E6%98%AF%E6%95%B4%E4%B8%AAView%EF%BC%8CgetLeft()%E4%BC%9A%E5%8F%98%E7%9A%84%EF%BC%8C**%E8%87%AA%E5%AE%9A%E4%B9%89View%E5%BE%88%E6%9C%89%E7%94%A8**%E3%80%82%20%7C%0A%7C%20offsetTopAndBottom(int%20offset)%20%7C%20%E5%9E%82%E7%9B%B4%E6%96%B9%E5%90%91%E6%8C%AA%E5%8A%A8View%EF%BC%8Coffset%E4%B8%BA%E6%AD%A3%E5%88%99y%E8%BD%B4%E6%AD%A3%E5%90%91%E7%A7%BB%E5%8A%A8%EF%BC%8C%E7%A7%BB%E5%8A%A8%E7%9A%84%E6%98%AF%E6%95%B4%E4%B8%AAView%EF%BC%8CgetTop()%E4%BC%9A%E5%8F%98%E7%9A%84%EF%BC%8C**%E8%87%AA%E5%AE%9A%E4%B9%89View%E5%BE%88%E6%9C%89%E7%94%A8**%E3%80%82%20%7C%0A%7C%20scrollTo(int%20x%2C%20int%20y)%20%20%20%20%20%20%20%20%20%7C%20%E5%B0%86**View%E4%B8%AD%E5%86%85%E5%AE%B9%EF%BC%88%E4%B8%8D%E6%98%AF%E6%95%B4%E4%B8%AAView%EF%BC%89**%E6%BB%91%E5%8A%A8%E5%88%B0%E7%9B%B8%E5%BA%94%E7%9A%84%E4%BD%8D%E7%BD%AE%EF%BC%8C%E5%8F%82%E8%80%83%E5%9D%90%E6%A0%87%E5%8E%9F%E7%82%B9%E4%B8%BAParentView%E5%B7%A6%E4%B8%8A%E8%A7%92%EF%BC%8Cx%EF%BC%8Cy%E4%B8%BA%E6%AD%A3%E5%88%99%E5%90%91xy%E8%BD%B4%E5%8F%8D%E6%96%B9%E5%90%91%E7%A7%BB%E5%8A%A8%EF%BC%8C%E5%8F%8D%E4%B9%8B%E5%90%8C%E7%90%86%E3%80%82%20%7C%0A%7C%20scrollBy(int%20x%2C%20int%20y)%20%20%20%20%20%20%20%20%20%7C%20%E5%9C%A8scrollTo()%E7%9A%84%E5%9F%BA%E7%A1%80%E4%B8%8A%E7%BB%A7%E7%BB%AD%E6%BB%91%E5%8A%A8xy%E3%80%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%7C%20setScrollX(int%20value)%20%20%20%20%20%20%20%20%20%20%7C%20%E5%AE%9E%E8%B4%A8%E4%B8%BAscrollTo()%EF%BC%8C%E5%8F%AA%E6%98%AF%E5%8F%AA%E6%94%B9%E5%8F%98Y%E8%BD%B4%E6%BB%91%E5%8A%A8%E3%80%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%7C%20setScrollY(int%20value)%20%20%20%20%20%20%20%20%20%20%7C%20%E5%AE%9E%E8%B4%A8%E4%B8%BAscrollTo()%EF%BC%8C%E5%8F%AA%E6%98%AF%E5%8F%AA%E6%94%B9%E5%8F%98X%E8%BD%B4%E6%BB%91%E5%8A%A8%E3%80%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%7C%20getScrollX()%2FgetScrollY()%20%20%20%20%20%20%7C%20%E8%8E%B7%E5%8F%96%E5%BD%93%E5%89%8D%E6%BB%91%E5%8A%A8%E4%BD%8D%E7%BD%AE%E5%81%8F%E7%A7%BB%E9%87%8F%E3%80%82%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%0A!%5B20bf4d1ebf995411b8a02cb7c418b614.png%5D(en-resource%3A%2F%2Fdatabase%2F633%3A0)%0A%0A%0A2.%20%E8%87%AA%E5%AE%9A%E4%B9%89view%E5%88%86%E7%B1%BB%0A%0A-%20%E8%87%AA%E5%AE%9A%E4%B9%89View%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%96%B9%E6%B3%95%0A%E8%87%AA%E5%AE%9A%E4%B9%89View%E7%9A%84%E6%9C%80%E5%9F%BA%E6%9C%AC%E7%9A%84%E4%B8%89%E4%B8%AA%E6%96%B9%E6%B3%95%E5%88%86%E5%88%AB%E6%98%AF%EF%BC%9A%20onMeasure()%E3%80%81onLayout()%E3%80%81onDraw()%3B%0AView%E5%9C%A8Activity%E4%B8%AD%E6%98%BE%E7%A4%BA%E5%87%BA%E6%9D%A5%EF%BC%8C%E8%A6%81%E7%BB%8F%E5%8E%86%E6%B5%8B%E9%87%8F%E3%80%81%E5%B8%83%E5%B1%80%E5%92%8C%E7%BB%98%E5%88%B6%E4%B8%89%E4%B8%AA%E6%AD%A5%E9%AA%A4%EF%BC%8C%E5%88%86%E5%88%AB%E5%AF%B9%E5%BA%94%E4%B8%89%E4%B8%AA%E5%8A%A8%E4%BD%9C%EF%BC%9Ameasure%E3%80%81layout%E5%92%8Cdraw%E3%80%82%0A%0A%20%20%20%20-%20%E6%B5%8B%E9%87%8F%EF%BC%9AonMeasure()%E5%86%B3%E5%AE%9AView%E7%9A%84%E5%A4%A7%E5%B0%8F%EF%BC%9B%0A%20%20%20%20-%20%E5%B8%83%E5%B1%80%EF%BC%9AonLayout()%E5%86%B3%E5%AE%9AView%E5%9C%A8ViewGroup%E4%B8%AD%E7%9A%84%E4%BD%8D%E7%BD%AE%EF%BC%9B%0A%20%20%20%20-%20%E7%BB%98%E5%88%B6%EF%BC%9AonDraw()%E5%86%B3%E5%AE%9A%E7%BB%98%E5%88%B6%E8%BF%99%E4%B8%AAView%E3%80%82%0A-%20%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8E%A7%E4%BB%B6%E5%88%86%E7%B1%BB%0A%20%20%20%20-%20%E8%87%AA%E5%AE%9A%E4%B9%89View%3A%20%E5%8F%AA%E9%9C%80%E8%A6%81%E9%87%8D%E5%86%99onMeasure()%E5%92%8ConDraw()%0A%20%20%20%20-%20%E8%87%AA%E5%AE%9A%E4%B9%89ViewGroup%3A%20%E5%88%99%E5%8F%AA%E9%9C%80%E8%A6%81%E9%87%8D%E5%86%99onMeasure()%E5%92%8ConLayout()%0A%0A-%20%E8%A7%86%E5%9B%BEView%E4%B8%BB%E8%A6%81%E5%88%86%E4%B8%BA%E4%B8%A4%E7%B1%BB%0A%0A%0A%7C%20%20%20%E7%B1%BB%E5%88%AB%20%20%20%7C%20%20%E8%A7%A3%E9%87%8A%20%20%20%20%7C%20%20%20%E7%89%B9%E7%82%B9%20%20%20%7C%0A%7C%20----%20%7C%20----%20%7C%20----%20%7C%0A%7C%20%20%20%E5%8D%95%E4%B8%80%E8%A7%86%E5%9B%BE%20%20%20%7C%20%20%20%E5%8D%B3%E4%B8%80%E4%B8%AAView%EF%BC%8C%E5%A6%82TextView%20%20%20%7C%20%20%E4%B8%8D%E5%8C%85%E5%90%AB%E5%AD%90View%20%20%20%20%7C%0A%7C%20%20%20%E8%A7%86%E5%9B%BE%E7%BB%84%20%20%20%7C%20%20%20%E5%8D%B3%E5%A4%9A%E4%B8%AAView%E7%BB%84%E6%88%90%E7%9A%84ViewGroup%EF%BC%8C%E5%A6%82LinearLayout%20%20%20%7C%20%20%E5%8C%85%E5%90%AB%E5%AD%90View%20%20%7C%0A%0A-%20View%E7%B1%BB%E7%AE%80%E4%BB%8B%0A%20%20%20%20-%20View%E7%B1%BB%E6%98%AFAndroid%E4%B8%AD%E5%90%84%E7%A7%8D%E7%BB%84%E4%BB%B6%E7%9A%84%E5%9F%BA%E7%B1%BB%EF%BC%8C%E5%A6%82View%E6%98%AFViewGroup%E5%9F%BA%E7%B1%BB%0A%20%20%20%20-%20View%E8%A1%A8%E7%8E%B0%E4%B8%BA%E6%98%BE%E7%A4%BA%E5%9C%A8%E5%B1%8F%E5%B9%95%E4%B8%8A%E7%9A%84%E5%90%84%E7%A7%8D%E8%A7%86%E5%9B%BE%0A%20%20%20%20%3E%20Android%E4%B8%AD%E7%9A%84UI%E7%BB%84%E4%BB%B6%E9%83%BD%E7%94%B1View%E3%80%81ViewGroup%E7%BB%84%E6%88%90%E3%80%82%0A%0A-%20View%E7%9A%84%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%EF%BC%9A%E5%85%B1%E6%9C%894%E4%B8%AA%0A%0A%60%60%60java%0A%2F%2F%20%E5%A6%82%E6%9E%9CView%E6%98%AF%E5%9C%A8Java%E4%BB%A3%E7%A0%81%E9%87%8C%E9%9D%A2new%E7%9A%84%EF%BC%8C%E5%88%99%E8%B0%83%E7%94%A8%E7%AC%AC%E4%B8%80%E4%B8%AA%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%0A%20%20%20public%20CustomView(Context%20context)%20%7B%0A%20%20%20%20%20%20%20%20%20%20super(context)%3B%0A%20%20%20%20%20%20%7D%0A%20%20%0A%20%20%2F%2F%20%E5%A6%82%E6%9E%9CView%E6%98%AF%E5%9C%A8.xml%E9%87%8C%E5%A3%B0%E6%98%8E%E7%9A%84%EF%BC%8C%E5%88%99%E8%B0%83%E7%94%A8%E7%AC%AC%E4%BA%8C%E4%B8%AA%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%0A%20%20%2F%2F%20%E8%87%AA%E5%AE%9A%E4%B9%89%E5%B1%9E%E6%80%A7%E6%98%AF%E4%BB%8EAttributeSet%E5%8F%82%E6%95%B0%E4%BC%A0%E8%BF%9B%E6%9D%A5%E7%9A%84%0A%20%20%20%20%20%20public%20%20CustomView(Context%20context%2C%20AttributeSet%20attrs)%20%7B%0A%20%20%20%20%20%20%20%20%20%20super(context%2C%20attrs)%3B%0A%20%20%20%20%20%20%7D%0A%20%20%0A%20%20%2F%2F%20%E4%B8%8D%E4%BC%9A%E8%87%AA%E5%8A%A8%E8%B0%83%E7%94%A8%0A%20%20%2F%2F%20%E4%B8%80%E8%88%AC%E6%98%AF%E5%9C%A8%E7%AC%AC%E4%BA%8C%E4%B8%AA%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%E9%87%8C%E4%B8%BB%E5%8A%A8%E8%B0%83%E7%94%A8%0A%20%20%2F%2F%20%E5%A6%82View%E6%9C%89style%E5%B1%9E%E6%80%A7%E6%97%B6%0A%20%20%20%20%20%20public%20%20CustomView(Context%20context%2C%20AttributeSet%20attrs%2C%20int%20defStyleAttr)%20%7B%0A%20%20%20%20%20%20%20%20%20%20super(context%2C%20attrs%2C%20defStyleAttr)%3B%0A%20%20%20%20%20%20%7D%0A%20%20%0A%20%20%20%20%20%20%2F%2FAPI21%E4%B9%8B%E5%90%8E%E6%89%8D%E4%BD%BF%E7%94%A8%0A%20%20%20%20%20%20%2F%2F%20%E4%B8%8D%E4%BC%9A%E8%87%AA%E5%8A%A8%E8%B0%83%E7%94%A8%0A%20%20%20%20%20%20%2F%2F%20%E4%B8%80%E8%88%AC%E6%98%AF%E5%9C%A8%E7%AC%AC%E4%BA%8C%E4%B8%AA%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%E9%87%8C%E4%B8%BB%E5%8A%A8%E8%B0%83%E7%94%A8%0A%20%20%20%20%20%20%2F%2F%20%E5%A6%82View%E6%9C%89style%E5%B1%9E%E6%80%A7%E6%97%B6%0A%20%20%20%20%20%20public%20%20CustomView(Context%20context%2C%20AttributeSet%20attrs%2C%20int%20defStyleAttr%2C%20int%20defStyleRes)%20%7B%0A%20%20%20%20%20%20%20%20%20%20super(context%2C%20attrs%2C%20defStyleAttr%2C%20defStyleRes)%3B%0A%20%20%20%20%20%20%7D%0A%60%60%60%0A%20%0A%20%20%0A-%20AttributeSet%E4%B8%8E%E8%87%AA%E5%AE%9A%E4%B9%89%E5%B1%9E%E6%80%A7%0A%E3%80%80%E7%B3%BB%E7%BB%9F%E8%87%AA%E5%B8%A6%E7%9A%84View%E5%8F%AF%E4%BB%A5%E5%9C%A8xml%E4%B8%AD%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%EF%BC%8C%E5%AF%B9%E4%BA%8E%E5%86%99%E7%9A%84%E5%A5%BD%E7%9A%84%E8%87%AA%E5%AE%9A%E4%B9%89View%E5%90%8C%E6%A0%B7%E5%8F%AF%E4%BB%A5%E5%9C%A8xml%E4%B8%AD%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%EF%BC%8C%E4%B8%BA%E4%BA%86%E4%BD%BF%E8%87%AA%E5%AE%9A%E4%B9%89%E7%9A%84View%E7%9A%84%E5%B1%9E%E6%80%A7%E5%8F%AF%E4%BB%A5%E5%9C%A8xml%E4%B8%AD%E9%85%8D%E7%BD%AE%EF%BC%8C%E9%9C%80%E8%A6%81%E4%BB%A5%E4%B8%8B4%E4%B8%AA%E6%AD%A5%E9%AA%A4%EF%BC%9A%0A%20%20%20%201.%20%E9%80%9A%E8%BF%87%60%60%60%3Cdeclare-styleable%3E%60%60%60%E4%B8%BA%E8%87%AA%E5%AE%9A%E4%B9%89View%E6%B7%BB%E5%8A%A0%E5%B1%9E%E6%80%A7%0A%20%20%20%202.%20%E5%9C%A8xml%E4%B8%AD%E4%B8%BA%E7%9B%B8%E5%BA%94%E7%9A%84%E5%B1%9E%E6%80%A7%E5%A3%B0%E6%98%8E%E5%B1%9E%E6%80%A7%E5%80%BC%0A%20%20%20%203.%20%E5%9C%A8%E8%BF%90%E8%A1%8C%E6%97%B6%EF%BC%88%E4%B8%80%E8%88%AC%E4%B8%BA%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%EF%BC%89%E8%8E%B7%E5%8F%96%E5%B1%9E%E6%80%A7%E5%80%BC%0A%20%20%20%204.%20%E5%B0%86%E8%8E%B7%E5%8F%96%E5%88%B0%E7%9A%84%E5%B1%9E%E6%80%A7%E5%80%BC%E5%BA%94%E7%94%A8%E5%88%B0View%0A%0A-%20%20View%E8%A7%86%E5%9B%BE%E7%BB%93%E6%9E%84%0A%20%20%20%201.%20PhoneWindow%E6%98%AFAndroid%E7%B3%BB%E7%BB%9F%E4%B8%AD%E6%9C%80%E5%9F%BA%E6%9C%AC%E7%9A%84%E7%AA%97%E5%8F%A3%E7%B3%BB%E7%BB%9F%EF%BC%8C%E7%BB%A7%E6%89%BF%E8%87%AAWindows%E7%B1%BB%EF%BC%8C%E8%B4%9F%E8%B4%A3%E7%AE%A1%E7%90%86%E7%95%8C%E9%9D%A2%E6%98%BE%E7%A4%BA%E4%BB%A5%E5%8F%8A%E4%BA%8B%E4%BB%B6%E5%93%8D%E5%BA%94%E3%80%82%E5%AE%83%E6%98%AFActivity%E4%B8%8EView%E7%B3%BB%E7%BB%9F%E4%BA%A4%E4%BA%92%E7%9A%84%E6%8E%A5%E5%8F%A3%0A%20%20%20%202.%20DecorView%E6%98%AFPhoneWindow%E4%B8%AD%E7%9A%84%E8%B5%B7%E5%A7%8B%E8%8A%82%E7%82%B9View%EF%BC%8C%E7%BB%A7%E6%89%BF%E4%BA%8EView%E7%B1%BB%EF%BC%8C%E4%BD%9C%E4%B8%BA%E6%95%B4%E4%B8%AA%E8%A7%86%E5%9B%BE%E5%AE%B9%E5%99%A8%E6%9D%A5%E4%BD%BF%E7%94%A8%E3%80%82%E7%94%A8%E4%BA%8E%E8%AE%BE%E7%BD%AE%E7%AA%97%E5%8F%A3%E5%B1%9E%E6%80%A7%E3%80%82%E5%AE%83%E6%9C%AC%E8%B4%A8%E4%B8%8A%E6%98%AF%E4%B8%80%E4%B8%AAFrameLayout%0A%20%20%20%203.%20ViewRoot%E5%9C%A8Activtiy%E5%90%AF%E5%8A%A8%E6%97%B6%E5%88%9B%E5%BB%BA%EF%BC%8C%E8%B4%9F%E8%B4%A3%E7%AE%A1%E7%90%86%E3%80%81%E5%B8%83%E5%B1%80%E3%80%81%E6%B8%B2%E6%9F%93%E7%AA%97%E5%8F%A3UI%E7%AD%89%E7%AD%89%0A%0A!%5Bce0b70755621f001ee445501dbe94e58.png%5D(en-resource%3A%2F%2Fdatabase%2F635%3A0)%0A%0A%E4%B8%8A%E5%9B%BE%E6%98%AF%20Activity%20%E7%9A%84%E7%BB%93%E6%9E%84%E3%80%82%E6%88%91%E4%BB%AC%E5%85%88%E8%BF%9B%E8%A1%8C%E5%A4%A7%E8%87%B4%E7%9A%84%E6%8F%8F%E8%BF%B0%EF%BC%8C%E7%84%B6%E5%90%8E%E5%9C%A8%E8%BF%9B%E5%85%A5%E6%BA%90%E7%A0%81%E4%BD%93%E4%BC%9A%E8%BF%99%E4%B8%80%E8%BF%87%E7%A8%8B%E3%80%82%0A%0A%E6%88%91%E4%BB%AC%E5%8F%AF%E4%BB%A5%E6%B8%85%E6%99%B0%E7%9A%84%E7%9F%A5%E9%81%93%E4%B8%80%E4%B8%AA%20Activity%20%E4%BC%9A%E5%AF%B9%E5%BA%94%E7%9D%80%E6%9C%89%E4%B8%80%E4%B8%AA%20Window%EF%BC%8C%E8%80%8C%C2%A0Window%20%E7%9A%84%E5%94%AF%E4%B8%80%E5%AE%9E%E7%8E%B0%E7%B1%BB%E4%B8%BA%20PhoneWindow%EF%BC%8CPhoneWindow%20%E7%9A%84%E5%88%9D%E5%A7%8B%E5%8C%96%E6%98%AF%E5%9C%A8%20Activity%20%E7%9A%84%C2%A0attach%C2%A0%E6%96%B9%E6%B3%95%E4%B8%AD%EF%BC%8C%E6%88%91%E4%BB%AC%E5%89%8D%E9%9D%A2%E4%B9%9F%E6%9C%89%E6%8F%90%E5%88%B0%C2%A0attach%C2%A0%E6%96%B9%E6%B3%95%E3%80%82%0A%0A%E5%9C%A8%E5%BE%80%E4%B8%8B%E4%B8%80%E5%B1%82%E6%98%AF%E4%B8%80%E4%B8%AA%20DecorView%EF%BC%8C%E8%A2%AB%20PhoneWindow%20%E6%8C%81%E6%9C%89%E7%9D%80%EF%BC%8CDecorView%20%E7%9A%84%E5%88%9D%E5%A7%8B%E5%8C%96%E5%9C%A8%20setContentView%20%E4%B8%AD%EF%BC%8C%E8%BF%99%E4%B8%AA%E6%88%91%E4%BB%AC%E5%BE%85%E4%BC%9A%E4%BC%9A%E8%BF%9B%E8%A1%8C%E8%AF%A6%E7%BB%86%E5%88%86%E6%9E%90%E3%80%82DecorView%20%E6%98%AF%E6%88%91%E4%BB%AC%E7%9A%84%E9%A1%B6%E7%BA%A7View%EF%BC%8C%E6%88%91%E4%BB%AC%E8%AE%BE%E7%BD%AE%E7%9A%84%E5%B8%83%E5%B1%80%E5%8F%AA%E6%98%AF%E5%85%B6%E5%AD%90View%E3%80%82%0A%0ADecorView%20%E6%98%AF%E4%B8%80%E4%B8%AA%20FrameLayout%E3%80%82%E4%BD%86%E5%9C%A8%C2%A0setContentView%C2%A0%E4%B8%AD%EF%BC%8C%E4%BC%9A%E7%BB%99%E4%BB%96%E5%8A%A0%E5%85%A5%E4%B8%80%E4%B8%AA%E7%BA%BF%E6%80%A7%E7%9A%84%E5%B8%83%E5%B1%80(LinearLayout)%E3%80%82%E8%AF%A5%E7%BA%BF%E6%80%A7%E5%B8%83%E5%B1%80%E7%9A%84%E5%AD%90View%20%E5%88%99%E4%B8%80%E8%88%AC%E7%94%B1%20TitleBar%20%E5%92%8C%20ContentView%20%E8%BF%9B%E8%A1%8C%E7%BB%84%E6%88%90%E3%80%82TitleBar%20%E6%88%91%E4%BB%AC%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%C2%A0requestWindowFeature(Window.FEATURE_NO_TITLE)%3B%C2%A0%E8%BF%9B%E8%A1%8C%E5%8E%BB%E9%99%A4%EF%BC%8C%E8%80%8C%C2%A0ContentView%20%E5%88%99%E6%98%AF%E6%9D%A5%E8%A3%85%E8%BD%BD%E6%88%91%E4%BB%AC%E8%AE%BE%E7%BD%AE%E7%9A%84%E5%B8%83%E5%B1%80%E6%96%87%E4%BB%B6%E7%9A%84%20ViewGroup%20%E4%BA%86%0A%0A%E5%AF%B9%E4%BA%8E%E5%A4%9AView%E7%9A%84%E8%A7%86%E5%9B%BE%EF%BC%8C%E7%BB%93%E6%9E%84%E6%98%AF%E6%A0%91%E5%BD%A2%E7%BB%93%E6%9E%84%EF%BC%9A%E6%9C%80%E9%A1%B6%E5%B1%82%E6%98%AFViewGroup%EF%BC%8CViewGroup%E4%B8%8B%E5%8F%AF%E8%83%BD%E6%9C%89%E5%A4%9A%E4%B8%AAViewGroup%E6%88%96View%EF%BC%8C%E5%A6%82%E4%B8%8B%E5%9B%BE%EF%BC%9A%0A%0A!%5B44fecb34f0ef7d0fc654719f83b36084.png%5D(en-resource%3A%2F%2Fdatabase%2F637%3A0)%0A%0A%0A%E4%B8%80%E5%AE%9A%E8%A6%81%E8%AE%B0%E4%BD%8F%EF%BC%9A%E6%97%A0%E8%AE%BA%E6%98%AFmeasure%E8%BF%87%E7%A8%8B%E3%80%81layout%E8%BF%87%E7%A8%8B%E8%BF%98%E6%98%AFdraw%E8%BF%87%E7%A8%8B%EF%BC%8C%E6%B0%B8%E8%BF%9C%E9%83%BD%E6%98%AF%E4%BB%8EView%E6%A0%91%E7%9A%84%E6%A0%B9%E8%8A%82%E7%82%B9%E5%BC%80%E5%A7%8B%E6%B5%8B%E9%87%8F%E6%88%96%E8%AE%A1%E7%AE%97%EF%BC%88%E5%8D%B3%E4%BB%8E%E6%A0%91%E7%9A%84%E9%A1%B6%E7%AB%AF%E5%BC%80%E5%A7%8B%EF%BC%89%EF%BC%8C%E4%B8%80%E5%B1%82%E4%B8%80%E5%B1%82%E3%80%81%E4%B8%80%E4%B8%AA%E5%88%86%E6%94%AF%E4%B8%80%E4%B8%AA%E5%88%86%E6%94%AF%E5%9C%B0%E8%BF%9B%E8%A1%8C%EF%BC%88%E5%8D%B3%E6%A0%91%E5%BD%A2%E9%80%92%E5%BD%92%EF%BC%89%EF%BC%8C%E6%9C%80%E7%BB%88%E8%AE%A1%E7%AE%97%E6%95%B4%E4%B8%AAView%E6%A0%91%E4%B8%AD%E5%90%84%E4%B8%AAView%EF%BC%8C%E6%9C%80%E7%BB%88%E7%A1%AE%E5%AE%9A%E6%95%B4%E4%B8%AAView%E6%A0%91%E7%9A%84%E7%9B%B8%E5%85%B3%E5%B1%9E%E6%80%A7%0A%0A%23%23%23%23%23%23%20view%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%0A!%5B56a5f83ecf4e5a00e591490a2025af3d.png%5D(en-resource%3A%2F%2Fdatabase%2F657%3A0)%0A%0A!%5B6ac07e73c625b91d94dfbf34b56fac46.png%5D(en-resource%3A%2F%2Fdatabase%2F659%3A0)%0A%0A%0A%23%23%23%23%20%E7%BB%98%E5%88%B6%E6%B5%81%E7%A8%8B%E4%BB%8E%E4%BD%95%E8%80%8C%E8%B5%B7%0A%0A%E6%88%91%E4%BB%AC%E4%B8%80%E8%AF%B4%E5%88%B0%E7%BB%98%E5%88%B6%E6%B5%81%E7%A8%8B%EF%BC%8C%E5%B0%B1%E4%BC%9A%E6%83%B3%E5%88%B0%E6%88%96%E6%98%AF%E5%90%AC%E8%BF%87onMeasure%E3%80%81onLayout%E3%80%81onDraw%E8%BF%99%E4%B8%89%E4%B8%AA%E6%96%B9%E6%B3%95%EF%BC%8C%E4%BD%86%E6%98%AF%E6%9C%89%E6%B2%A1%E6%83%B3%E8%BF%87%E4%B8%BA%E4%BB%80%E4%B9%88%E6%88%91%E4%BB%AC%E5%BC%80%E5%90%AF%E4%B8%80%E4%B8%AAApp%E6%88%96%E6%98%AF%E7%82%B9%E5%BC%80%E4%B8%80%E4%B8%AAActivity%EF%BC%8C%E5%B0%B1%E4%BC%9A%E8%A7%A6%E5%8F%91%E8%BF%99%E4%B8%80%E7%B3%BB%E5%88%97%E6%B5%81%E7%A8%8B%E5%91%A2%EF%BC%9F%E6%83%B3%E7%9F%A5%E9%81%93%E7%BB%98%E5%88%B6%E6%B5%81%E7%A8%8B%E4%BB%8E%E4%BD%95%E8%80%8C%E8%B5%B7%EF%BC%8C%E6%88%91%E4%BB%AC%E5%B0%B1%E6%9C%89%E5%BF%85%E8%A6%81%E5%85%88%E8%A7%A3%E9%87%8A%C2%A0App%E5%90%AF%E5%8A%A8%E6%B5%81%E7%A8%8B%C2%A0%E5%92%8C%C2%A0Activity%E7%9A%84%E5%90%AF%E5%8A%A8%E6%B5%81%E7%A8%8B%E3%80%82%E6%88%91%E4%BB%AC%E9%83%BD%E7%9F%A5%E9%81%93%20%0A%0A%3E%20ActivityThread%20%E7%9A%84%C2%A0main%C2%A0%E6%98%AF%E4%B8%80%E4%B8%AAApp%E7%9A%84%E5%85%A5%E5%8F%A3%E3%80%82%E6%88%91%E4%BB%AC%E6%9D%A5%E5%88%B0%C2%A0main%C2%A0%E6%96%B9%E6%B3%95%E7%9C%8B%E7%9C%8B%E4%BB%96%E5%81%9A%E4%BA%86%E4%BB%80%E4%B9%88%E5%90%AF%E5%8A%A8%E6%93%8D%E4%BD%9C%E3%80%82ActivityThread%20%E7%9A%84%C2%A0main%E6%96%B9%E6%B3%95%E6%98%AF%E7%94%B1%20ZygoteInit%20%E7%B1%BB%E4%B8%AD%E6%9C%80%E7%BB%88%E9%80%9A%E8%BF%87%20RuntimeInit%E7%B1%BB%E7%9A%84invokeStaticMain%C2%A0%E6%96%B9%E6%B3%95%E8%BF%9B%E8%A1%8C%E5%8F%8D%E5%B0%84%E8%B0%83%E7%94%A8%0A%0A!%5B01b5beffba302a16c1e1eee51d1ed4c6.png%5D(en-resource%3A%2F%2Fdatabase%2F639%3A0)%0A%0A!%5B6a781efd70511f5c855d8ea320dd2faa.png%5D(en-resource%3A%2F%2Fdatabase%2F641%3A0)%0A%0A-%20measure%E6%B5%81%E7%A8%8B%0A%0A!%5Bbf7e5ff8c71528019b1999a683a38348.png%5D(en-resource%3A%2F%2Fdatabase%2F643%3A0)%0A%0A-%20layout%E6%B5%81%E7%A8%8B%0A%0A!%5Bbe633a6a5a62eef1003d5b976f27e8d7.png%5D(en-resource%3A%2F%2Fdatabase%2F645%3A0)%0A%0A-%20draw%E6%B5%81%E7%A8%8B%0A%0A!%5B521b7e21b927f2b298ddb73fa5f379db.png%5D(en-resource%3A%2F%2Fdatabase%2F647%3A0)%0A%0A-%20%E5%88%B7%E6%96%B0%0A%0A!%5B6486e6f6419c83761dff71aaf22378c6.png%5D(en-resource%3A%2F%2Fdatabase%2F661%3A0)%0A%0A%0A%0A%0A%23%23%23%23%20%E6%B5%8B%E9%87%8F%E6%98%AF%E5%A6%82%E4%BD%95%E8%BF%9B%E8%A1%8C%E7%9A%84%0A%0A%0A-%20%E6%B5%8B%E9%87%8F%E9%81%8D%E5%8E%86%E5%9C%A8%C2%A0measure(int%2C%20int)%C2%A0%E4%B8%AD%E5%AE%9E%E7%8E%B0%EF%BC%8C%E6%98%AF%C2%A0View%C2%A0%E6%A0%91%E7%9A%84%E8%87%AA%E4%B8%8A%E8%80%8C%E4%B8%8B%E9%81%8D%E5%8E%86%E3%80%82%E5%9C%A8%E9%80%92%E5%BD%92%E8%BF%87%E7%A8%8B%E4%B8%AD%EF%BC%8C%E6%AF%8F%E4%B8%AA%C2%A0View%C2%A0%E9%83%BD%E4%BC%9A%E5%B0%86%E7%BB%B4%E5%BA%A6%E8%A7%84%E8%8C%83%E4%B8%8B%E6%8E%A8%E5%88%B0%E5%B8%83%E5%B1%80%E6%A0%91%E3%80%82%E5%9C%A8%E6%B5%8B%E9%87%8F%E9%81%8D%E5%8E%86%E7%BB%93%E6%9D%9F%E6%97%B6%EF%BC%8C%E6%AF%8F%E4%B8%AA%C2%A0View%C2%A0%E5%9D%87%E5%AD%98%E5%82%A8%E4%BA%86%E5%85%B6%E6%B5%8B%E9%87%8F%E5%80%BC%E3%80%82%E7%AC%AC%E4%BA%8C%E6%AC%A1%E9%81%8D%E5%8E%86%E5%8F%91%E7%94%9F%E5%9C%A8%C2%A0layout(int%2C%20int%2C%20int%2C%20int)%C2%A0%E4%B8%AD%EF%BC%8C%E4%B9%9F%E6%98%AF%E8%87%AA%E4%B8%8A%E8%80%8C%E4%B8%8B%E9%81%8D%E5%8E%86%E3%80%82%E5%9C%A8%E6%AD%A4%E6%AC%A1%E9%81%8D%E5%8E%86%E4%B8%AD%EF%BC%8C%E6%AF%8F%E4%B8%AA%E7%88%B6%E7%BA%A7%E8%B4%9F%E8%B4%A3%E4%BD%BF%E7%94%A8%E6%B5%8B%E9%87%8F%E9%81%8D%E5%8E%86%E4%B8%AD%E8%AE%A1%E7%AE%97%E7%9A%84%E5%B0%BA%E5%AF%B8%E6%9D%A5%E5%AE%9A%E4%BD%8D%E5%85%B6%E6%89%80%E6%9C%89%E7%9A%84%E5%AD%90%E7%BA%A7%E3%80%82%E5%BD%93%E8%BF%94%E5%9B%9E%C2%A0View%C2%A0%E5%AF%B9%E8%B1%A1%E7%9A%84%C2%A0measure()%C2%A0%E6%96%B9%E6%B3%95%E6%97%B6%EF%BC%8C%E5%BF%85%E9%A1%BB%E8%AE%BE%E7%BD%AE%E5%85%B6%C2%A0getMeasuredWidth()%C2%A0%E5%92%8C%C2%A0getMeasuredHeight()%C2%A0%E5%80%BC%EF%BC%8C%E4%BB%A5%E5%8F%8A%E8%AF%A5%C2%A0View%C2%A0%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%89%80%E6%9C%89%E5%AD%90%E7%BA%A7%E7%9A%84%E5%80%BC%E3%80%82View%C2%A0%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%B5%8B%E9%87%8F%E5%AE%BD%E5%BA%A6%E5%80%BC%E5%92%8C%E6%B5%8B%E9%87%8F%E9%AB%98%E5%BA%A6%E5%80%BC%E5%BF%85%E9%A1%BB%E9%81%B5%E5%AE%88%C2%A0View%C2%A0%E5%AF%B9%E8%B1%A1%E7%9A%84%E7%88%B6%E7%BA%A7%E6%89%80%E6%96%BD%E5%8A%A0%E7%9A%84%E9%99%90%E5%88%B6%E3%80%82%E8%BF%99%E5%B0%B1%E4%BF%9D%E8%AF%81%E4%BA%86%E5%9C%A8%E6%B5%8B%E9%87%8F%E9%81%8D%E5%8E%86%E7%BB%93%E6%9D%9F%E6%97%B6%EF%BC%8C%E6%89%80%E6%9C%89%E7%88%B6%E7%BA%A7%E9%83%BD%E4%BC%9A%E6%8E%A5%E5%8F%97%E5%85%B6%E5%AD%90%E7%BA%A7%E7%9A%84%E6%89%80%E6%9C%89%E6%B5%8B%E9%87%8F%E5%80%BC%E3%80%82%E7%88%B6%E7%BA%A7%C2%A0View%C2%A0%E5%8F%AF%E4%BB%A5%E5%AF%B9%E5%85%B6%E5%AD%90%E7%BA%A7%E5%A4%9A%E6%AC%A1%E8%B0%83%E7%94%A8%C2%A0measure()%E3%80%82%E4%BE%8B%E5%A6%82%EF%BC%8C%E7%88%B6%E7%BA%A7%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8%E6%9C%AA%E6%8C%87%E5%AE%9A%E7%9A%84%E7%BB%B4%E5%BA%A6%E6%B5%8B%E9%87%8F%E6%AF%8F%E4%B8%AA%E5%AD%90%E7%BA%A7%E4%B8%80%E6%AC%A1%EF%BC%8C%E4%BB%A5%E7%A1%AE%E5%AE%9A%E5%AE%83%E4%BB%AC%E5%B8%8C%E6%9C%9B%E7%9A%84%E5%A4%A7%E5%B0%8F%EF%BC%9B%E7%84%B6%E5%90%8E%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%89%80%E6%9C%89%E5%AD%90%E7%BA%A7%E4%B8%8D%E5%8F%97%E9%99%90%E5%88%B6%E7%9A%84%E5%B0%BA%E5%AF%B8%E7%9A%84%E6%80%BB%E5%92%8C%E8%BF%87%E5%A4%A7%E6%88%96%E8%BF%87%E5%B0%8F%EF%BC%8C%E5%88%99%E5%86%8D%E6%AC%A1%E4%BD%BF%E7%94%A8%E5%AE%9E%E9%99%85%E7%9A%84%E6%95%B0%E5%AD%97%E5%AF%B9%E5%AE%83%E4%BB%AC%E8%B0%83%E7%94%A8%C2%A0measure()%EF%BC%88%E5%8D%B3%EF%BC%8C%E5%A6%82%E6%9E%9C%E5%AD%90%E7%BA%A7%E6%9C%AA%E5%B0%B1%E5%90%84%E8%87%AA%E8%8E%B7%E5%BE%97%E5%A4%9A%E5%B0%91%E7%A9%BA%E9%97%B4%E8%BE%BE%E6%88%90%E4%B8%80%E8%87%B4%EF%BC%8C%E5%88%99%E7%88%B6%E7%BA%A7%E5%B0%86%E4%BC%9A%E4%BB%8B%E5%85%A5%E5%B9%B6%E9%92%88%E5%AF%B9%E7%AC%AC%E4%BA%8C%E6%AC%A1%E9%81%8D%E5%8E%86%E8%AE%BE%E7%BD%AE%E8%A7%84%E5%88%99%EF%BC%89%E3%80%82%0A%0A-%20%E6%B5%8B%E9%87%8F%E9%81%8D%E5%8E%86%E4%BD%BF%E7%94%A8%E4%B8%A4%E4%B8%AA%E7%B1%BB%E6%9D%A5%E4%BC%A0%E8%BE%BE%E7%BB%B4%E5%BA%A6%E3%80%82View%C2%A0%E5%AF%B9%E8%B1%A1%E4%BD%BF%E7%94%A8%C2%A0ViewGroup.LayoutParams%C2%A0%E7%B1%BB%E6%9D%A5%E5%91%8A%E7%9F%A5%E7%88%B6%E7%BA%A7%E5%AE%83%E4%BB%AC%E6%83%B3%E8%A6%81%E5%A6%82%E4%BD%95%E6%B5%8B%E9%87%8F%E5%92%8C%E5%AE%9A%E4%BD%8D%E3%80%82%E5%9F%BA%E6%9C%AC%E7%9A%84%C2%A0ViewGroup.LayoutParams%C2%A0%E7%B1%BB%E4%BB%85%E6%8F%8F%E8%BF%B0%E4%BA%86%C2%A0View%C2%A0%E5%B8%8C%E6%9C%9B%E7%9A%84%E5%AE%BD%E5%BA%A6%E5%92%8C%E9%AB%98%E5%BA%A6%E3%80%82%E9%92%88%E5%AF%B9%E6%AF%8F%E4%B8%AA%E7%BB%B4%E5%BA%A6%EF%BC%8C%E5%AE%83%E5%8F%AF%E4%BB%A5%E6%8C%87%E5%AE%9A%E4%BB%A5%E4%B8%8B%E6%9F%90%E4%B8%80%E9%A1%B9%EF%BC%9A%0A%20%20%20%20-%20%E4%B8%80%E4%B8%AA%E7%A1%AE%E5%88%87%E7%9A%84%E6%95%B0%E5%AD%97%0A%20%20%20%20-%20MATCH_PARENT%EF%BC%8C%E8%AF%A5%E5%8F%82%E6%95%B0%E6%84%8F%E5%91%B3%E7%9D%80%C2%A0View%C2%A0%E6%83%B3%E8%A6%81%E5%92%8C%E5%AE%83%E7%9A%84%E7%88%B6%E7%BA%A7%E4%B8%80%E6%A0%B7%E5%A4%A7%EF%BC%88%E8%B4%9F%E5%A1%AB%E5%85%85%EF%BC%89%0A%20%20%20%20-%20WRAP_CONTENT%EF%BC%8C%E8%AF%A5%E5%8F%82%E6%95%B0%E6%84%8F%E5%91%B3%E7%9D%80%C2%A0View%C2%A0%E6%83%B3%E8%A6%81%E8%B6%B3%E5%A4%9F%E5%A4%A7%EF%BC%8C%E4%BB%A5%E5%8C%85%E5%90%AB%E5%85%B6%E5%86%85%E5%AE%B9%EF%BC%88%E6%AD%A3%E5%A1%AB%E5%85%85%EF%BC%89%E3%80%82%0A%20%0A%E6%9C%89%E9%80%82%E7%94%A8%E4%BA%8E%C2%A0ViewGroup%C2%A0%E7%9A%84%E4%B8%8D%E5%90%8C%E5%AD%90%E7%B1%BB%E7%9A%84%C2%A0ViewGroup.LayoutParams%C2%A0%E5%AD%90%E7%B1%BB%E3%80%82%E4%BE%8B%E5%A6%82%EF%BC%8CRelativeLayout%C2%A0%E6%9C%89%E8%87%AA%E5%B7%B1%E7%9A%84%C2%A0ViewGroup.LayoutParams%C2%A0%E5%AD%90%E7%B1%BB%EF%BC%8C%E5%85%B6%E4%B8%AD%E5%8C%85%E6%8B%AC%E4%BD%BF%E5%AD%90%E7%BA%A7%C2%A0View%C2%A0%E5%AF%B9%E8%B1%A1%E6%B0%B4%E5%B9%B3%E5%92%8C%E5%9E%82%E7%9B%B4%E5%B1%85%E4%B8%AD%E7%9A%84%E5%8A%9F%E8%83%BD%E3%80%82%0A%0AMeasureSpec%C2%A0%E5%AF%B9%E8%B1%A1%E7%94%A8%E4%BA%8E%E5%9C%A8%E6%A0%91%E4%B8%AD%E5%B0%86%E8%A6%81%E6%B1%82%E4%BB%8E%E7%88%B6%E7%BA%A7%E4%B8%8B%E6%8E%A8%E5%88%B0%E5%AD%90%E7%BA%A7%E3%80%82MeasureSpec%C2%A0%E5%8F%AF%E4%BB%A5%E4%B8%BA%E4%BB%A5%E4%B8%8B%E4%B8%89%E7%A7%8D%E6%A8%A1%E5%BC%8F%E4%B9%8B%E4%B8%80%EF%BC%9A%0A-%20UNSPECIFIED%EF%BC%9A%E7%88%B6%E7%BA%A7%E4%BD%BF%E7%94%A8%E8%AF%A5%E6%A8%A1%E5%BC%8F%E6%9D%A5%E7%A1%AE%E5%AE%9A%E5%AD%90%E7%BA%A7%C2%A0View%C2%A0%E6%89%80%E9%9C%80%E7%9A%84%E7%BB%B4%E5%BA%A6%E3%80%82%E4%BE%8B%E5%A6%82%EF%BC%8CLinearLayout%C2%A0%E5%8F%AF%E8%83%BD%E4%BC%9A%E5%AF%B9%E5%85%B6%E9%AB%98%E5%BA%A6%E8%AE%BE%E7%BD%AE%E4%B8%BA%C2%A0UNSPECIFIED%C2%A0%E5%92%8C%E5%AE%BD%E5%BA%A6%E8%AE%BE%E7%BD%AE%E4%B8%BA%C2%A0EXACTLY%C2%A0240%20%E7%9A%84%E5%AD%90%E7%BA%A7%E8%B0%83%E7%94%A8%C2%A0measure()%EF%BC%8C%E4%BB%8E%E8%80%8C%E7%A1%AE%E5%AE%9A%E5%AE%BD%E5%BA%A6%E4%B8%BA%20240%20%E5%83%8F%E7%B4%A0%E7%9A%84%E5%AD%90%E7%BA%A7%C2%A0View%C2%A0%E6%89%80%E9%9C%80%E7%9A%84%E9%AB%98%E5%BA%A6%E3%80%82%0A-%20EXACTLY%EF%BC%9A%E7%88%B6%E7%BA%A7%E4%BD%BF%E7%94%A8%E8%AF%A5%E6%A8%A1%E5%BC%8F%E6%9D%A5%E5%BC%BA%E5%88%B6%E5%AD%90%E7%BA%A7%E4%BD%BF%E7%94%A8%E6%9F%90%E4%B8%AA%E7%A1%AE%E5%88%87%E5%B0%BA%E5%AF%B8%E3%80%82%E5%AD%90%E7%BA%A7%E5%BF%85%E9%A1%BB%E4%BD%BF%E7%94%A8%E8%AF%A5%E5%B0%BA%E5%AF%B8%EF%BC%8C%E5%B9%B6%E4%BF%9D%E8%AF%81%E5%85%B6%E6%89%80%E6%9C%89%E7%9A%84%E5%AD%90%E9%A1%B9%E9%83%BD%E8%83%BD%E6%94%BE%E5%85%A5%E8%AF%A5%E5%B0%BA%E5%AF%B8%E3%80%82%0A-%20AT%20MOST%EF%BC%9A%E7%88%B6%E7%BA%A7%E4%BD%BF%E7%94%A8%E8%AF%A5%E6%A8%A1%E5%BC%8F%E6%9D%A5%E5%BC%BA%E5%88%B6%E8%A7%84%E5%AE%9A%E5%AD%90%E7%BA%A7%E7%9A%84%E6%9C%80%E5%A4%A7%E5%B0%BA%E5%AF%B8%E3%80%82%E5%AD%90%E7%BA%A7%E5%BF%85%E9%A1%BB%E4%BF%9D%E8%AF%81%E5%AE%83%E5%8F%8A%E5%85%B6%E6%89%80%E6%9C%89%E7%9A%84%E5%AD%90%E9%A1%B9%E9%83%BD%E8%83%BD%E6%94%BE%E5%85%A5%E8%AF%A5%E5%B0%BA%E5%AF%B8%0A%0A!%5Be15d94e3ef93a1ffe3408403ce080fda.png%5D(en-resource%3A%2F%2Fdatabase%2F649%3A0)%0A%0A%0A%60%60%60java%0A%2F%2F%20ViewGroup%20%E7%B1%BB%0Apublic%20static%20int%20getChildMeasureSpec(int%20spec%2C%20int%20padding%2C%20int%20childDimension)%20%7B%0A%20%20%20%20int%20specMode%20%3D%20MeasureSpec.getMode(spec)%3B%0A%20%20%20%20int%20specSize%20%3D%20MeasureSpec.getSize(spec)%3B%0A%0A%20%20%20%20int%20size%20%3D%20Math.max(0%2C%20specSize%20-%20padding)%3B%0A%0A%20%20%20%20int%20resultSize%20%3D%200%3B%0A%20%20%20%20int%20resultMode%20%3D%200%3B%0A%0A%20%20%20%20switch%20(specMode)%20%7B%0A%20%20%20%20%20%20%20%20%2F%2F%20%E7%88%B6%E8%A7%86%E5%9B%BE%E4%B8%BA%E7%A1%AE%E5%AE%9A%E7%9A%84%E5%A4%A7%E5%B0%8F%E7%9A%84%E6%A8%A1%E5%BC%8F%0A%20%20%20%20%20%20%20%20case%20MeasureSpec.EXACTLY%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20%E6%A0%B9%E6%8D%AE%E5%AD%90%E8%A7%86%E5%9B%BE%E7%9A%84%E5%A4%A7%E5%B0%8F%EF%BC%8C%E8%BF%9B%E8%A1%8C%E4%B8%8D%E5%90%8C%E6%A8%A1%E5%BC%8F%E7%9A%84%E7%BB%84%E5%90%88%EF%BC%9A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%201%E3%80%81childDimension%20%E5%A4%A7%E4%BA%8E%200%EF%BC%8C%E8%AF%B4%E6%98%8E%E5%AD%90%E8%A7%86%E5%9B%BE%E8%AE%BE%E7%BD%AE%E4%BA%86%E5%85%B7%E4%BD%93%E7%9A%84%E5%A4%A7%E5%B0%8F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%202%E3%80%81childDimension%20%E4%B8%BA%20%7B%40link%20LayoutParams.MATCH_PARENT%7D%EF%BC%8C%E8%AF%B4%E6%98%8E%E5%A4%A7%E5%B0%8F%E5%92%8C%E5%85%B6%E7%88%B6%E8%A7%86%E5%9B%BE%E4%B8%80%E6%A0%B7%E5%A4%A7%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%203%E3%80%81childDimension%20%E4%B8%BA%20%7B%40link%20LayoutParams.WRAP_CONTENT%7D%EF%BC%8C%E8%AF%B4%E6%98%8E%E5%AD%90%E8%A7%86%E5%9B%BE%E6%83%B3%E4%B8%BA%E5%85%B6%E8%87%AA%E5%B7%B1%E7%9A%84%E5%A4%A7%E5%B0%8F%EF%BC%8C%E4%BD%86%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20%E4%B8%8D%E8%83%BD%E8%B6%85%E8%BF%87%E5%85%B6%E7%88%B6%E8%A7%86%E5%9B%BE%E7%9A%84%E5%A4%A7%E5%B0%8F%E3%80%82%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(childDimension%20%3E%3D%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resultSize%20%3D%20childDimension%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resultMode%20%3D%20MeasureSpec.EXACTLY%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(childDimension%20%3D%3D%20LayoutParams.MATCH_PARENT)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Child%20wants%20to%20be%20our%20size.%20So%20be%20it.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resultSize%20%3D%20size%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resultMode%20%3D%20MeasureSpec.EXACTLY%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(childDimension%20%3D%3D%20LayoutParams.WRAP_CONTENT)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Child%20wants%20to%20determine%20its%20own%20size.%20It%20can't%20be%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20bigger%20than%20us.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resultSize%20%3D%20size%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resultMode%20%3D%20MeasureSpec.AT_MOST%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20break%3B%0A%20%20%20%20%20%20%20%20%2F%2F%20%E7%88%B6%E8%A7%86%E5%9B%BE%E5%B7%B2%E7%BB%8F%E6%9C%89%E4%B8%80%E4%B8%AA%E6%9C%80%E5%A4%A7%E5%B0%BA%E5%AF%B8%E9%99%90%E5%88%B6%0A%20%20%20%20%20%20%20%20case%20MeasureSpec.AT_MOST%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F**%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20%E6%A0%B9%E6%8D%AE%E5%AD%90%E8%A7%86%E5%9B%BE%E7%9A%84%E5%A4%A7%E5%B0%8F%EF%BC%8C%E8%BF%9B%E8%A1%8C%E4%B8%8D%E5%90%8C%E6%A8%A1%E5%BC%8F%E7%9A%84%E7%BB%84%E5%90%88%EF%BC%9A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%201%E3%80%81childDimension%20%E5%A4%A7%E4%BA%8E%200%EF%BC%8C%E8%AF%B4%E6%98%8E%E5%AD%90%E8%A7%86%E5%9B%BE%E8%AE%BE%E7%BD%AE%E4%BA%86%E5%85%B7%E4%BD%93%E7%9A%84%E5%A4%A7%E5%B0%8F%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%202%E3%80%81childDimension%20%E4%B8%BA%20%7B%40link%20LayoutParams.MATCH_PARENT%7D%EF%BC%8C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20-----%E8%AF%B4%E6%98%8E%E5%A4%A7%E5%B0%8F%E5%92%8C%E5%85%B6%E7%88%B6%E8%A7%86%E5%9B%BE%E4%B8%80%E6%A0%B7%E5%A4%A7%EF%BC%8C%E4%BD%86%E6%98%AF%E6%AD%A4%E6%97%B6%E7%9A%84%E7%88%B6%E8%A7%86%E5%9B%BE%E8%BF%98%E4%B8%8D%E8%83%BD%E7%A1%AE%E5%AE%9A%E5%85%B6%E5%A4%A7%E5%B0%8F%EF%BC%8C%E6%89%80%E4%BB%A5%E5%8F%AA%E8%83%BD%E8%AE%A9%E5%AD%90%E8%A7%86%E5%9B%BE%E4%B8%8D%E8%B6%85%E8%BF%87%E8%87%AA%E5%B7%B1%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%203%E3%80%81childDimension%20%E4%B8%BA%20%7B%40link%20LayoutParams.WRAP_CONTENT%7D%EF%BC%8C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%20-----%E8%AF%B4%E6%98%8E%E5%AD%90%E8%A7%86%E5%9B%BE%E6%83%B3%E4%B8%BA%E5%85%B6%E8%87%AA%E5%B7%B1%E7%9A%84%E5%A4%A7%E5%B0%8F%EF%BC%8C%E4%BD%86%E4%B8%8D%E8%83%BD%E8%B6%85%E8%BF%87%E5%85%B6%E7%88%B6%E8%A7%86%E5%9B%BE%E7%9A%84%E5%A4%A7%E5%B0%8F%E3%80%82%0A%20%20%20%20%20%20%20%20%20%20%20%20%20*%2F%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(childDimension%20%3E%3D%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Child%20wants%20a%20specific%20size...%20so%20be%20it%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resultSize%20%3D%20childDimension%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resultMode%20%3D%20MeasureSpec.EXACTLY%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(childDimension%20%3D%3D%20LayoutParams.MATCH_PARENT)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Child%20wants%20to%20be%20our%20size%2C%20but%20our%20size%20is%20not%20fixed.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Constrain%20child%20to%20not%20be%20bigger%20than%20us.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resultSize%20%3D%20size%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resultMode%20%3D%20MeasureSpec.AT_MOST%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(childDimension%20%3D%3D%20LayoutParams.WRAP_CONTENT)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Child%20wants%20to%20determine%20its%20own%20size.%20It%20can't%20be%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20bigger%20than%20us.%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resultSize%20%3D%20size%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resultMode%20%3D%20MeasureSpec.AT_MOST%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20break%3B%0A%20%20%20%20%20%20%20%20case%20MeasureSpec.UNSPECIFIED%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(childDimension%20%3E%3D%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Child%20wants%20a%20specific%20size...%20let%20him%20have%20it%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resultSize%20%3D%20childDimension%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resultMode%20%3D%20MeasureSpec.EXACTLY%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(childDimension%20%3D%3D%20LayoutParams.MATCH_PARENT)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Child%20wants%20to%20be%20our%20size...%20find%20out%20how%20big%20it%20should%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20be%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resultSize%20%3D%20View.sUseZeroUnspecifiedMeasureSpec%20%3F%200%20%3A%20size%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resultMode%20%3D%20MeasureSpec.UNSPECIFIED%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if%20(childDimension%20%3D%3D%20LayoutParams.WRAP_CONTENT)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Child%20wants%20to%20determine%20its%20own%20size....%20find%20out%20how%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20big%20it%20should%20be%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resultSize%20%3D%20View.sUseZeroUnspecifiedMeasureSpec%20%3F%200%20%3A%20size%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20resultMode%20%3D%20MeasureSpec.UNSPECIFIED%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20break%3B%0A%20%20%20%20%7D%0A%20%20%20%20return%20MeasureSpec.makeMeasureSpec(resultSize%2C%20resultMode)%3B%7D%0A%60%60%60%0A%0A!%5B3b133760a36909db1f27699908d83373.png%5D(en-resource%3A%2F%2Fdatabase%2F651%3A0)%0A%0A%E9%92%88%E5%AF%B9%E4%B8%8A%E8%A1%A8%EF%BC%8C%E8%BF%99%E9%87%8C%E5%86%8D%E5%81%9A%E4%B8%80%E4%B8%8B%E5%85%B7%E4%BD%93%E7%9A%84%E8%AF%B4%E6%98%8E%0A%0A-%20%E5%AF%B9%E4%BA%8E%E5%BA%94%E7%94%A8%E5%B1%82%20View%20%EF%BC%8C%E5%85%B6%20MeasureSpec%20%E7%94%B1%E7%88%B6%E5%AE%B9%E5%99%A8%E7%9A%84%20MeasureSpec%20%E5%92%8C%E8%87%AA%E8%BA%AB%E7%9A%84%20LayoutParams%20%E6%9D%A5%E5%85%B1%E5%90%8C%E5%86%B3%E5%AE%9A%0A-%20%E5%AF%B9%E4%BA%8E%E4%B8%8D%E5%90%8C%E7%9A%84%E7%88%B6%E5%AE%B9%E5%99%A8%E5%92%8Cview%E6%9C%AC%E8%BA%AB%E4%B8%8D%E5%90%8C%E7%9A%84LayoutParams%EF%BC%8Cview%E5%B0%B1%E5%8F%AF%E4%BB%A5%E6%9C%89%E5%A4%9A%E7%A7%8DMeasureSpec%E3%80%82%0A%20%20%20%20%20%201.%20%20%E5%BD%93view%E9%87%87%E7%94%A8%E5%9B%BA%E5%AE%9A%E5%AE%BD%E9%AB%98%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E4%B8%8D%E7%AE%A1%E7%88%B6%E5%AE%B9%E5%99%A8%E7%9A%84MeasureSpec%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%8Cview%E7%9A%84MeasureSpec%E9%83%BD%E6%98%AF%E7%B2%BE%E7%A1%AE%E6%A8%A1%E5%BC%8F%E5%B9%B6%E4%B8%94%E5%85%B6%E5%A4%A7%E5%B0%8F%E9%81%B5%E5%BE%AALayoutparams%E4%B8%AD%E7%9A%84%E5%A4%A7%E5%B0%8F%EF%BC%9B%0A%20%20%20%20%20%202.%20%E5%BD%93view%E7%9A%84%E5%AE%BD%E9%AB%98%E6%98%AFmatch_parent%E6%97%B6%EF%BC%8C%E8%BF%99%E4%B8%AA%E6%97%B6%E5%80%99%E5%A6%82%E6%9E%9C%E7%88%B6%E5%AE%B9%E5%99%A8%E7%9A%84%E6%A8%A1%E5%BC%8F%E6%98%AF%E7%B2%BE%E5%87%86%E6%A8%A1%E5%BC%8F%EF%BC%8C%E9%82%A3%E4%B9%88view%E4%B9%9F%E6%98%AF%E7%B2%BE%E5%87%86%E6%A8%A1%E5%BC%8F%E5%B9%B6%E4%B8%94%E5%85%B6%E5%A4%A7%E5%B0%8F%E6%98%AF%E7%88%B6%E5%AE%B9%E5%99%A8%E7%9A%84%E5%89%A9%E4%BD%99%E7%A9%BA%E9%97%B4%EF%BC%8C%E5%A6%82%E6%9E%9C%E7%88%B6%E5%AE%B9%E5%99%A8%E6%98%AF%E6%9C%80%E5%A4%A7%E6%A8%A1%E5%BC%8F%EF%BC%8C%E9%82%A3%E4%B9%88view%E4%B9%9F%E6%98%AF%E6%9C%80%E5%A4%A7%E6%A8%A1%E5%BC%8F%E5%B9%B6%E4%B8%94%E5%85%B6%E5%A4%A7%E5%B0%8F%E4%B8%8D%E4%BC%9A%E8%B6%85%E8%BF%87%E7%88%B6%E5%AE%B9%E5%99%A8%E7%9A%84%E5%89%A9%E4%BD%99%E7%A9%BA%E9%97%B4%EF%BC%9B%0A%20%20%20%20%20%203.%20%20%E5%BD%93view%E7%9A%84%E5%AE%BD%E9%AB%98%E6%98%AFwrap_content%E6%97%B6%EF%BC%8C%E4%B8%8D%E7%AE%A1%E7%88%B6%E5%AE%B9%E5%99%A8%E7%9A%84%E6%A8%A1%E5%BC%8F%E6%98%AF%E7%B2%BE%E5%87%86%E8%BF%98%E6%98%AF%E6%9C%80%E5%A4%A7%E5%8C%96%EF%BC%8Cview%E7%9A%84%E6%A8%A1%E5%BC%8F%E6%80%BB%E6%98%AF%E6%9C%80%E5%A4%A7%E5%8C%96%E5%B9%B6%E4%B8%94%E5%A4%A7%E5%B0%8F%E4%B8%8D%E8%83%BD%E8%B6%85%E8%BF%87%E7%88%B6%E5%AE%B9%E5%99%A8%E7%9A%84%E5%89%A9%E4%BD%99%E7%A9%BA%E9%97%B4%E3%80%82%0A%20%20%20%20%204.%20Unspecified%E6%A8%A1%E5%BC%8F%EF%BC%8C%E8%BF%99%E4%B8%AA%E6%A8%A1%E5%BC%8F%E4%B8%BB%E8%A6%81%E7%94%A8%E4%BA%8E%E7%B3%BB%E7%BB%9F%E5%86%85%E9%83%A8%E5%A4%9A%E6%AC%A1measure%E7%9A%84%E6%83%85%E5%86%B5%E4%B8%8B%EF%BC%8C%E4%B8%80%E8%88%AC%E6%9D%A5%E8%AF%B4%EF%BC%8C%E6%88%91%E4%BB%AC%E4%B8%8D%E9%9C%80%E8%A6%81%E5%85%B3%E6%B3%A8%E6%AD%A4%E6%A8%A1%E5%BC%8F(%E8%BF%99%E9%87%8C%E6%B3%A8%E6%84%8F%E8%87%AA%E5%AE%9A%E4%B9%89View%E6%94%BE%E5%88%B0ScrollView%E7%9A%84%E6%83%85%E5%86%B5%20%E9%9C%80%E8%A6%81%E5%A4%84%E7%90%86)%E3%80%82%0A%0A%23%23%23%23%23%23%20onMeasure()%E6%96%B9%E6%B3%95%E4%B8%AD%E5%B8%B8%E7%94%A8%E7%9A%84%E6%96%B9%E6%B3%95%0A1.%20getChildCount()%EF%BC%9A%E8%8E%B7%E5%8F%96%E5%AD%90View%E7%9A%84%E6%95%B0%E9%87%8F%EF%BC%9B%0A2.%20getChildAt(i)%EF%BC%9A%E8%8E%B7%E5%8F%96%E7%AC%ACi%E4%B8%AA%E5%AD%90%E6%8E%A7%E4%BB%B6%EF%BC%9B%0A3.%20%20subView.getLayoutParams().width%2Fheight%EF%BC%9A%E8%AE%BE%E7%BD%AE%E6%88%96%E8%8E%B7%E5%8F%96%E5%AD%90%E6%8E%A7%E4%BB%B6%E7%9A%84%E5%AE%BD%E6%88%96%E9%AB%98%EF%BC%9B%0A4.%20measureChild(child%2C%20widthMeasureSpec%2C%20heightMeasureSpec)%EF%BC%9A%E6%B5%8B%E9%87%8F%E5%AD%90View%E7%9A%84%E5%AE%BD%E9%AB%98%EF%BC%9B%0A5.%20child.getMeasuredHeight%2Fwidth()%EF%BC%9A%E6%89%A7%E8%A1%8C%E5%AE%8CmeasureChild()%E6%96%B9%E6%B3%95%E5%90%8E%E5%B0%B1%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E8%BF%99%E7%A7%8D%E6%96%B9%E5%BC%8F%E8%8E%B7%E5%8F%96%E5%AD%90View%E7%9A%84%E5%AE%BD%E9%AB%98%E5%80%BC%EF%BC%9B%0A6.%20getPaddingLeft%2FRight%2FTop%2FBottom()%EF%BC%9A%E8%8E%B7%E5%8F%96%E6%8E%A7%E4%BB%B6%E7%9A%84%E5%9B%9B%E5%91%A8%E5%86%85%E8%BE%B9%E8%B7%9D%EF%BC%9B%0A7.%20setMeasuredDimension(width%2C%20height)%EF%BC%9A%E9%87%8D%E6%96%B0%E8%AE%BE%E7%BD%AE%E6%8E%A7%E4%BB%B6%E7%9A%84%E5%AE%BD%E9%AB%98%0A%0A%23%23%23%23%23%23%20%E8%87%AA%E5%AE%9A%E4%B9%89View%E9%9C%80%E8%A6%81%E6%B3%A8%E6%84%8F%E7%9A%84%E5%9C%B0%E6%96%B9%0A-%20%E8%AE%A9View%E6%94%AF%E6%8C%81wrap_conent%0A-%20%E8%AE%A9View%E6%94%AF%E6%8C%81padding%0A-%20%E5%B0%BD%E9%87%8F%E9%81%BF%E5%85%8D%E4%BD%BF%E7%94%A8Handler%EF%BC%8C%E4%B8%80%E8%88%AC%E9%83%BD%E5%8F%AF%E4%BB%A5%E7%94%A8View%E8%87%AA%E5%B8%A6%E7%9A%84post%E6%96%B9%E6%B3%95%E4%BB%A3%E6%9B%BF%0A-%20%E5%9C%A8onDeatchFromWindow%E6%97%B6%EF%BC%8C%E5%81%9C%E6%AD%A2View%E7%9A%84%E5%8A%A8%E7%94%BB%E6%88%96%E7%BA%BF%E7%A8%8B%EF%BC%88%E5%A6%82%E6%9E%9C%E6%9C%89%E7%9A%84%E8%AF%9D%EF%BC%89%0A-%20%E5%A6%82%E6%9E%9C%E5%AD%98%E5%9C%A8%E5%B5%8C%E5%A5%97%E6%BB%91%E5%8A%A8%EF%BC%8C%E5%A4%84%E7%90%86%E5%A5%BD%E6%BB%91%E5%8A%A8%E5%86%B2%E7%AA%81%0A%0A%0A%23%23%23%23%23%23%20%E8%87%AA%E5%AE%9A%E4%B9%89View%E5%A6%82%E4%BD%95%E6%B5%8B%E9%87%8F%0A!%5Bd7bb657797c5b73692770848568a1a15.png%5D(en-resource%3A%2F%2Fdatabase%2F653%3A0)%0A%0A%23%23%23%23%20%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BB%98%E5%88%B6%0A%0A1.%20Canvas%E5%B8%B8%E7%94%A8%E6%96%B9%E6%B3%95%0A%20%20%20%20-%20%E7%BB%98%E5%88%B6%E5%9B%BE%E5%BD%A2%EF%BC%88%E7%82%B9%E3%80%81%E7%BA%BF%E3%80%81%E7%9F%A9%E5%BD%A2%E3%80%81%E6%A4%AD%E5%9C%86%E3%80%81%E5%9C%86%E7%AD%89%EF%BC%89%0A%20%20%20%20-%20%E7%BB%98%E5%88%B6%E6%96%87%E6%9C%AC%EF%BC%88%E6%96%87%E6%9C%AC%E7%9A%84%E5%B1%85%E4%B8%AD%E9%97%AE%E9%A2%98%EF%BC%8C%E9%9C%80%E8%A6%81Paint%E7%9F%A5%E8%AF%86%EF%BC%89%0A%20%20%20%20-%20%E7%94%BB%E5%B8%83%E7%9A%84%E5%9F%BA%E6%9C%AC%E5%8F%98%E5%8C%96%EF%BC%88%E5%B9%B3%E7%A7%BB%E3%80%81%E7%BC%A9%E6%94%BE%E3%80%81%E6%97%8B%E8%BD%AC%E3%80%81%E5%80%BE%E6%96%9C%EF%BC%89%0A%20%20%20%20-%20%E7%94%BB%E5%B8%83%E7%9A%84%E8%A3%81%E5%89%AA%0A%20%20%20%20-%20%E7%94%BB%E5%B8%83%E7%9A%84%E4%BF%9D%E5%AD%98%0A%20%20%20%20!%5B86b5783152201d8d9f005ef4bc7cf772.png%5D(en-resource%3A%2F%2Fdatabase%2F667%3A0)%0A%0A2.%20Paint%E7%B1%BB%E4%B8%BB%E8%A6%81%E7%94%A8%E4%BA%8E%E8%AE%BE%E7%BD%AE%E7%BB%98%E5%88%B6%E9%A3%8E%E6%A0%BC%EF%BC%9A%E5%8C%85%E6%8B%AC%E7%94%BB%E7%AC%94%E7%9A%84%E9%A2%9C%E8%89%B2%E7%94%BB%E7%AC%94%E8%A7%A6%E7%AC%94%E7%B2%97%E7%BB%86%E3%80%81%E5%A1%AB%E5%85%85%E9%A3%8E%E6%A0%BC%E5%8F%8A%E6%96%87%E5%AD%97%E7%9A%84%E7%89%B9%E5%BE%81%0A-%20Paint%E5%B8%B8%E7%94%A8%E6%96%B9%E6%B3%95%0A%20%20%20%20-%20%E9%A2%9C%E8%89%B2%0A%20%20%20%20-%20%E7%B1%BB%E5%9E%8B%EF%BC%88%E5%A1%AB%E5%85%85%E3%80%81%E6%8F%8F%E8%BE%B9%EF%BC%89%0A%20%20%20%20-%20%E5%AD%97%E4%BD%93%E5%A4%A7%E5%B0%8F%0A%20%20%20%20-%20%E5%AE%BD%E5%BA%A6%0A%20%20%20%20-%20%E5%AF%B9%E9%BD%90%E6%96%B9%E5%BC%8F%0A%20%20%20%20-%20%E6%96%87%E5%AD%97%E4%BD%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E6%B5%8B%E9%87%8F%0A%20%20%20%20-%20%E6%96%87%E5%AD%97%E5%AE%BD%E5%BA%A6%E6%B5%8B%E9%87%8F%0A%20%20%20%20!%5Bad7432d84d8cee645e08324e37686afd.png%5D(en-resource%3A%2F%2Fdatabase%2F663%3A0)%0A%20%20%20%20!%5B3215afe11aa70927ade4e184a0a2720b.png%5D(en-resource%3A%2F%2Fdatabase%2F665%3A0)%0A%20%20%20%20%0A%0A%0A3.%20Path%E5%B8%B8%E7%94%A8%E6%96%B9%E6%B3%95%0A%20%20%20%20-%20%E6%B7%BB%E5%8A%A0%E8%B7%AF%E5%BE%84%0A%20%20%20%20-%20%E7%A7%BB%E5%8A%A8%E8%B5%B7%E7%82%B9%0A%20%20%20%20-%20%E8%B4%9D%E5%A1%9E%E5%B0%94%EF%BC%88%E4%BA%8C%E9%98%B6%E3%80%81%E4%B8%89%E9%98%B6%EF%BC%89%0A%20%20%20%20-%20%E9%80%BB%E8%BE%91%E8%BF%90%E7%AE%97%0A%20%20%20%20-%20%E9%87%8D%E7%BD%AE%E8%B7%AF%E5%BE%84%0A%20%20%20%20-%20PathEffect%0A%20%20%20%20-%20Matrix%0A%20%20%20%20-%20PathMeasure%0A%0A%0A-%20PorterDuffXfermode%0A!%5B9f8298e5c3396f03a9e5ccc0cf4aae62.png%5D(en-resource%3A%2F%2Fdatabase%2F669%3A0)%0A%20%0A%20%0A%20-%20Matrix%0A!%5Bd87977f3cbebb6cb229eb35410249cd0.png%5D(en-resource%3A%2F%2Fdatabase%2F671%3A0)%0A%0A-%20%E5%B9%B3%E7%A7%BB%E7%9F%A9%E9%98%B5%0A!%5B6c992ebcfe324f513690d2fa58d4d5dc.png%5D(en-resource%3A%2F%2Fdatabase%2F673%3A0)%0A%0A-%20%E7%BC%A9%E6%94%BE%E7%9F%A9%E9%98%B5%0A!%5Bf841197a003524574249fdad832f268f.png%5D(en-resource%3A%2F%2Fdatabase%2F675%3A0)%0A%0A-%20%E6%97%8B%E8%BD%AC%E7%9F%A9%E9%98%B5%0A!%5B73f9fa0cdf6437f7d599aff41051fa8d.png%5D(en-resource%3A%2F%2Fdatabase%2F677%3A0)%0A%0A%0A-%20ColorMatrix%0A%0A%0A%7C%20%E7%B1%BB%E5%88%AB%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20%20API%20%20%20%20%20%20%20%20%20%20%7C%20%E6%8F%8F%E8%BF%B0%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%7C%20%3A-------%20%7C%20%3A-------------------%3A%20%7C%20%3A-------------------------------%20%7C%0A%7C%20%E6%97%8B%E8%BD%AC%20%20%20%20%20%7C%20%20%20%20%20%20%20setRotate%20%20%20%20%20%20%20%7C%20%E8%AE%BE%E7%BD%AE(%E9%9D%9E%E8%BE%93%E5%85%A5%E8%BD%B4%E9%A2%9C%E8%89%B2%E7%9A%84)%E8%89%B2%E8%B0%83%20%20%20%20%20%20%20%20%20%7C%0A%7C%20%E9%A5%B1%E5%92%8C%E5%BA%A6%20%20%20%7C%20%20%20%20%20setSaturation%20%20%20%20%20%7C%20%E8%AE%BE%E7%BD%AE%E9%A5%B1%E5%92%8C%E5%BA%A6%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%7C%20%E7%BC%A9%E6%94%BE%20%20%20%20%20%7C%20%20%20%20%20%20%20setScale%20%20%20%20%20%20%20%20%7C%20%E4%B8%89%E5%8E%9F%E8%89%B2%E7%9A%84%E5%8F%96%E5%80%BC%E7%9A%84%E6%AF%94%E4%BE%8B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%7C%20%E8%AE%BE%E7%BD%AE%20%20%20%20%20%7C%20%20%20%20set%E3%80%81setConcat%20%20%20%20%20%7C%20%E8%AE%BE%E7%BD%AE%E9%A2%9C%E8%89%B2%E7%9F%A9%E9%98%B5%E3%80%81%E4%B8%A4%E4%B8%AA%E9%A2%9C%E8%89%B2%E7%9F%A9%E9%98%B5%E7%9A%84%E4%B9%98%E7%A7%AF%20%7C%0A%7C%20%E9%87%8D%E7%BD%AE%20%20%20%20%20%7C%20%20%20%20%20%20%20%20%20reset%20%20%20%20%20%20%20%20%20%7C%20%E9%87%8D%E7%BD%AE%E9%A2%9C%E8%89%B2%E7%9F%A9%E9%98%B5%E4%B8%BA%E5%88%9D%E5%A7%8B%E7%8A%B6%E6%80%81%20%20%20%20%20%20%20%20%20%20%20%7C%0A%7C%20%E7%9F%A9%E9%98%B5%E8%BF%90%E7%AE%97%20%7C%20preConcat%E3%80%81postConcat%20%7C%20%E9%A2%9C%E8%89%B2%E7%9F%A9%E9%98%B5%E7%9A%84%E5%89%8D%E4%B9%98%E3%80%81%E5%90%8E%E4%B9%98%20%20%20%20%20%20%20%20%20%20%20%20%20%7C%0A%0A%0A4.%20%E5%8A%A8%E7%94%BB%0A%20%20%20%20-%20ObjectAnimator%0A%20%20%20%20-%20ValueAnimator%0A%20%20%20%20-%20AnimatorSet%0A%20%20%20%20-%20%E5%B7%AE%E5%80%BC%E5%99%A8%0A%20%20%20%20-%20%E4%BC%B0%E5%80%BC%E5%99%A8%0A%0A%23%23%23%23%20%E4%BA%8B%E4%BB%B6%E5%88%86%E5%8F%91%0A-%20%E4%BA%8B%E4%BB%B6%E5%BA%8F%E5%88%97%20DOWN%20-%3E%20...%20MOVE%20....%20-%3E%20UP%2FCANCEL%0A%0A!%5B34576ec44520267c451ddb70e301fa95.png%5D(en-resource%3A%2F%2Fdatabase%2F655%3A0)%0A-%20%E7%88%B6%E5%AE%B9%E5%99%A8%E8%B0%83%E7%94%A8%E5%93%AA%E4%B8%AA%E6%96%B9%E6%B3%95%E5%8F%AF%E4%BB%A5%E6%8B%A6%E6%88%AA%E5%AD%90View%E7%9A%84%E4%BA%8B%E4%BB%B6%EF%BC%9F%E4%B8%BA%E4%BB%80%E4%B9%88%EF%BC%9F%0A%20%20-%20%E8%B0%83%E7%94%A8onInterceptTouchEvent()%E5%B9%B6%E8%BF%94%E5%9B%9Etrue%E3%80%82%E5%9B%A0%E4%B8%BA%E8%AF%A5%E6%96%B9%E6%B3%95%E8%BF%94%E5%9B%9Etrue%E5%90%8E%EF%BC%8C%E4%BC%9A%E5%AF%BC%E8%87%B4%E5%8F%98%E9%87%8F%20intercepted%20%3D%20true%EF%BC%8C%E4%BB%8E%E8%80%8C%E5%AF%BC%E8%87%B4%E4%B8%8D%E4%BC%9A%E8%B5%B0%E5%90%8E%E9%9D%A2%E5%88%86%E5%8F%91%E4%BA%8B%E4%BB%B6%E7%9A%84%E4%BB%A3%E7%A0%81%E3%80%82%0A-%20%E5%AD%90View%E8%B0%83%E7%94%A8%E5%93%AA%E4%B8%AA%E6%96%B9%E6%B3%95%E5%8F%AF%E4%BB%A5%E8%AF%B7%E6%B1%82%E7%88%B6%E5%AE%B9%E5%99%A8%E4%B8%8D%E6%8B%A6%E6%88%AA%E8%87%AA%E5%B7%B1%EF%BC%9F%E4%B8%BA%E4%BB%80%E4%B9%88%EF%BC%9F%0A%20%20-%20requestDisallowInterceptTouchEvent(true)%E3%80%82%E5%9B%A0%E4%B8%BA%20onInterceptTouchEvent()%20%E6%96%B9%E6%B3%95%E7%9A%84%E6%89%A7%E8%A1%8C%E6%9D%A1%E4%BB%B6%E6%98%AFdisallowIntercept%20%3D%20false%EF%BC%8C%E8%80%8C%E5%AD%90View%E8%B0%83%E7%94%A8requestDisallowInterceptTouchEvent(true)%E6%96%B9%E6%B3%95%E5%8F%AF%E4%BB%A5%E5%AF%BC%E8%87%B4disallowIntercept%20%3D%20true%EF%BC%8C%E4%BB%8E%E8%80%8ConInterceptTouchEvent%E6%96%B9%E6%B3%95%E4%B8%8D%E4%BC%9A%E6%89%A7%E8%A1%8C%EF%BC%8C%E7%88%B6%E5%AE%B9%E5%99%A8%E5%B0%B1%E4%B8%8D%E8%83%BD%E6%8B%A6%E6%88%AA%E8%87%AA%E5%B7%B1%E4%BA%86%E3%80%82%0A-%20%E7%88%B6%E5%AE%B9%E5%99%A8%E4%B8%80%E6%97%A6%E5%9C%A8down%E4%BA%8B%E4%BB%B6%E6%8B%A6%E6%88%AA%E5%AD%90View%EF%BC%8C%E5%B0%B1%E7%AE%97%E5%AD%90View%E8%B0%83%E7%94%A8%E4%BA%86requestDisallowInterceptTouchEvent%E6%96%B9%E6%B3%95%E8%BF%98%E6%98%AF%E6%8B%BF%E4%B8%8D%E5%88%B0%E4%BA%8B%E4%BB%B6%EF%BC%8C%E4%B8%BA%E4%BB%80%E4%B9%88%EF%BC%9F%0A%20%20-%20%E5%9B%A0%E4%B8%BAdown%E4%BA%8B%E4%BB%B6%E6%97%B6%EF%BC%8C%E7%88%B6%E5%AE%B9%E5%99%A8%E4%BC%9A%E8%B0%83%E7%94%A8resetTouchState%EF%BC%8C%E5%AF%BC%E8%87%B4disallowIntercept%E5%A7%8B%E7%BB%88%E4%B8%BAfalse%EF%BC%8C%E5%8D%B3onInterceptTouchEvent%E6%96%B9%E6%B3%95%E5%A7%8B%E7%BB%88%E4%BC%9A%E6%89%A7%E8%A1%8C%E3%80%82%0A-%20%E6%8C%89%E9%92%AE%E7%9A%84onClick%E6%96%B9%E6%B3%95%E6%98%AF%E5%9C%A8%E5%93%AA%E4%B8%AA%E4%BA%8B%E4%BB%B6%E5%93%8D%E5%BA%94%E7%9A%84%EF%BC%9F%0A%20%20-%20A.MotionEvent.ACTION_UP%0A%20%20-%20B.MotionEvent.ACTION_DOWN%0A%20%20-%20C.MotionEvent.ACTION_MOVE%0A-%20%E8%A7%A3%E5%86%B3%E4%BA%8B%E4%BB%B6%E5%86%B2%E7%AA%81%E7%9A%84%E4%B8%BB%E8%A6%81%E6%96%B9%E6%B3%95%E6%9C%89%E5%93%AA%E4%BA%9B%EF%BC%9F%0A%20%20-%20%E5%86%85%E9%83%A8%E6%8B%A6%E6%88%AA%E6%B3%95%E3%80%81%E5%A4%96%E9%83%A8%E6%8B%A6%E6%88%AA%E6%B3%95%0A%0A</center></span>
</div></body></html>